TARGET parameter in request handler can be abused as an open redirector
Description
Environment
Activity
Scott Cantor February 15, 2011 at 11:45 AM
I have an initial fix for this that adds a Sessions/@relayStateLimit option (none|exact|host|whitelist) to limit externally supplied redirects.
http://svn.shibboleth.net/view/cpp-sp?view=revision&revision=3403
I'm not enabling it by default to avoid breaking any current deployments, but am going to revisit that in the next release, as well as adjusting the fix to make it a public API. I'll open a separate RFE to track that.
Because there's no public API, I left the fix out of the ADFS plugin, which doesn't seem like a big deal at this point. I'll correct that in the next release also.
Scott Cantor February 11, 2011 at 12:23 PM
In your example, the attacker could simply obfuscate the URL in a variety of other ways and still get the victim to the bad site and do bad things, and at no time does the victim see themselves interacting with the "safe" domain. At least in the login case, you actually have a workflow that may imply to the user that they'll end up on the safe site, logged in. That's clearly worse. I can disable or limit the return option without totally breaking SLO, but it breaks some user interface flows involving it, that's all. Time will tell.
Your example there is what I meant by IdP-initiated SSO and it's a standard use case. To outright limit the use of URL-based relay state, I would have to preclude that, or build in a totally new way of indicating target resources through OOB configuration of relay state tokens. That's something one could do, but it would annoy people, and I can't break what people already do with their portals, so the better choice there is just to try and limit where the target can live.
If you want to be scared, I can tell you about all the other obscure web attacks that IdP-initated SSO makes easier. And you can see from the list that if we disabled it, people would shoot us. C'est la vie.
I don't think you're overreacting exactly, but it's sort of like plugging a hole in a dam with your finger. If I can improve things without making the configuration too complex, I think that's worth doing,
André Cruz February 11, 2011 at 12:09 PM
An example using the logout scenario would be an email sent to a victim with a link like
"https://safe.domain.com/Shibboleth.sso/Logout?TARGET=http://attacker.com" which prompted the victim to do something at site "safe.domain.com". The victim would probably believe the link to be real, since the domain is correct, and after following the link would end up at "attacker.com" which had a copy of the login page of "safe.domain.com". I think most users would not notice the altered domain, specially if it similar, and would enter their credentials. I understand if Front-side SLO is doomed, I'll just have to disable it.
Regarding my example, if was only to show that the SP would follow the target parameter whatever it is. But if you want a more concrete case a link can be constructed like:
A victim following that link in an email might expect to end up at login.xxxxx.xxx, which would be safe. I also tried to construct a link starting in the SP, using the target parameter, but the SP is configured with a relative handlerURL so I ended up with an error on the IDP, but I didn't try too hard.
But, I may be overreacting, that's also an option.
Scott Cantor February 11, 2011 at 9:43 AM
I'm not sure what harm it does in a logout scenario given that there's not even a hint that you're interacting with any site other than the one you end up on, and all you've done is at most destroy the user's session with the real site, but suffice to say it will be much harder to do anything about it. Probably I'll have to create a separate option to block use of the return option for those that aren't using it.
Another point I wanted to note is that in your particular example, you're imagining a case where the attacker can interfere with the response from the IdP before it gets to the SP in order to change the target value. If you could do that, you could just easily skip the SP altogether and redirect the form itself to post to the malicious site (or in fact probably steal the user's login outright by stealing the assertion). No need to change the target.
The real threat, such as it is, on the login side seems to be IdP-initiated SSO, since that's the case in which the target is likely to be settable by the attacker without having to get in the middle.
André Cruz February 11, 2011 at 3:17 AM
Regarding logout, I think it is also a problem since if I'm thinking correctly the browser will be redirected without any interaction at the legitimate site, right (not even a login is done)?
I imagine it like this: the user follows the link with the correct hostname, immediately ends up at the rogue site which can even ask for credentials to login. Users are not the brightest things.
I think you're moving in the right direction.
The target parameter used in several handlers stores either a reference to a relay state stored somewhere else (cookie, SS) or it can store the URL itself.
The problem is that this URL can be altered and SP will blindly forward the browser. This can be abused for phishing since the URL a user click has the correct host but the browser ends up somewhere else because it was a link to the session initiator with the target parameter set to a malicious URL. Probably restricting the URL to a relative URL will break some setups, but at least restricting the state type to the one chosen in the configuration would maybe suffice.
For example, even if I choose to use the relay state in a cookie the SP will accept an URL and use it.
Example request:
19:31:36.521[2034ms][total 2034ms] Status: 302[Found]
POST https://spaces.internet2.edu/Shibboleth.sso/SAML/POST Load Flags[LOAD_DOCUMENT_URI LOAD_INITIAL_DOCUMENT_URI ] Content Size[300] Mime Type[text/html]
Request Headers:
Host[spaces.internet2.edu]
...
Post Data:
TARGET[cookie%3Aa1ba7533]
SAMLResponse[PFJlc3B...D%0A]
Response Headers:
Date[Thu, 10 Feb 2011 19:31:37 GMT]
Server[Apache/2.2.3 (Red Hat)]
Set-Cookie[_shibstate_a1ba7533=; path=/; expires=Mon, 01 Jan 2001 00:00:00 GMT
_shibsession_64656661756c7468747470733a2f2f7370616365732e696e7465726e6574322e6564752f73686962626f6c657468=_d79ecb837bb417df20f4a746814eb17e; path=/]
Locationhttps://spaces.internet2.edu/
Content-Length[300]
Connection[close]
Content-Type[text/html; charset=iso-8859-1]
Example altered request:
19:33:36.245[2118ms][total 2118ms] Status: 302[Found]
POST https://spaces.internet2.edu/Shibboleth.sso/SAML/POST Load Flags[LOAD_DOCUMENT_URI LOAD_INITIAL_DOCUMENT_URI ] Content Size[291] Mime Type[text/html]
Request Headers:
Host[spaces.internet2.edu]
...
Post Data:
TARGEThttp://slashdot.org/
SAMLResponse[PFJlc3...%0A]
Response Headers:
Date[Thu, 10 Feb 2011 19:33:37 GMT]
Server[Apache/2.2.3 (Red Hat)]
Set-Cookie[_shibsession_64656661756c7468747470733a226f6c657468=_f92a1292bc875e64da42b08474b94e49; path=/]
Locationhttp://slashdot.org/
Content-Length[291]
Connection[close]
Content-Type[text/html; charset=iso-8859-1]