CSRF

V3.1 and above include the first implementation of a Cross-Site Request Forgery mitigation feature that blocks the acceptance of "unsolicited" SSO and Logout Response messages. Unsolicited SSO is a required feature of SAML but is by its nature a CSRF attack that allows a subject to hand over their own authenticated session to another party. This opens up somewhat obscure, but potentially viable, attacks against certain kinds of applications.

The mitigation is accomplished by recording the request message ID in a cookie that is correlated by name to the RelayState value sent with the request, and then recovering the message ID and verifying that the message's InResponseTo value matches.

This mechanism is fragile due to the common practice of sloppy hostname handling (initiating SSO on one hostname but redirecting responses to a different hostname). For example, a request from "https://www.service.example.org" won't correlate to a response to "https://service.example.org". In addition, many scenarios involving browsers being launched from other applications in response to clicking on hyperlinks tend to mishandle cookies set on the initial request. These are the same reasons that led to the abandoning of cookie-backed relay state in the default configuration, so this feature essentially reintroduces the same set of problems, but in an even more fatal way.

As such, it is doubtful that this feature will be of use to most applications and is off by default.

In theory, there are two separate features: message correlation and blocking unsolicited messages. In practice, there is no compelling reason to do the former except to do the latter, so they go hand in hand.

A brief comment about request signing: this is really an orthogonal feature that is neither necessary, nor sufficient, to achieve either goal. There is a loose connection in the sense that by both signing requests and requiring correlated responses, it's theoretically possible for an SP that trusted its IdPs to verify the request signature to assume that the content was unmolested and that the IdP may have honored its request. This can in theory allow an SP to skip certain enforcement steps such as validating Authentication Context classes or enforcing authentication freshness. In practice, those steps are large trivial to implement with the SP and so there is little value in offloading it.

Enabling Protection

To block unsolicited responses globally, you must:

  1. Make sure the security-policy.xml file is updated with the "blockUnsolicited" policy from the newly distributed version of the file (obviously unnecessary for new installs).
  2. Add a policyId XML attribute set to "blockUnsolicited" to one of the many places it can appear. For global enforcement, just add it to the <ApplicationDefaults> element.