Multiple shib_state cookies get set -> server chokes on header field size

Description

The Service Provider sets multiple shib_state cookies in case there is a public web page that does not require a Shibboleth session but that contains URLs to media files (css, images, ...) which point Shibboleth-protected URLs on the same host. In that case the SP will set a shib_state cookie for each request to such a media file. So, if the page contains links to x media files, x shib_state cookies will be set. And hitting reload will set another x cookies. These cookies are also not deleted when the user gets a Shibboleth session for that SP. The result is that the user will accumulate shib_state cookies until he quits the browser (which for some users can take a few days).

At some point the browser has set so many cookies for that host that the webserver complains with:
Bad Request
Your browser sent a request that this server could not understand.
Size of a request header field exceeds server limit.
Cookie

In this state it helps only to quit the browser or delete the cookies for this host in some other way. If the browser allows a third-party cookies, this probably can even be used to "DoS" a remote server. Just lure the user to a page of yours that has many long links to a host where an SP is installed e.g. to https://wiki.shibboleth.net/secure/this/is/a/dummy/link.jpg Depending on how many cookies are set and what maximum header size the webserver on wiki.shibboleth.net has set, the user won't be available anymore to access wiki.shibboleth.net until the cookies are deleted again.

A proof of concept is (temporarily) available at:
https://kelimutu.switch.ch/
Hit reload a few times and then check how many cookies you have set

Environment

None

Activity

Scott Cantor May 3, 2012 at 4:40 PM

http://svn.shibboleth.net/view/cpp-sp?rev=3638&view=rev

Cookies now include the timestamp along with a random key and are sorted for purging, oldest first, when the count exceeds the value specified in the relayState setting (cookie:n), defaulting to 25.

Scott Cantor April 26, 2012 at 2:34 PM

No, doing that would break framed sites due to race conditions.

Lukas Hämmerle April 26, 2012 at 2:09 PM

Isn't there a way to ensure that there is at all times only one single shib_state cookie set for a client? Before setting a new cookie, couldn't the SP first check whether this client already sent a shib_state cookie with the current request?

Scott Cantor April 26, 2012 at 2:04 PM

Using cookies with an actual expiration time probably isn't a good fix, since that would assume synchronized time with the client, and still allows for the problem to happen anyway.

While switching to alternate relay state helps, this would recur as soon as I add a mechanism to prevent IdP-initiated SSO to mitigate XSRF. That requires a cookie in exactly the same way, no other solution works with a standard browser that I know of.

Using non-random cookie names derived from the URL would address the frame issue, but wouldn't address the DoS possibility, since you could have many different resources triggering this, and given enough, the new ones wouldn't overwrite the old ones and it would still get too large.

I would guess that trying to impose a limit on the number of cookies used might work, but would certainly break some scenarios. As long as it's adjustable, though, with a reasonable default, I would assume that won't cause too many problems. And I don't see any other solution here.

Lukas Hämmerle April 26, 2012 at 1:08 PM

I just noticed that there recently was a post describing the same problem:
http://shibboleth.1660669.n2.nabble.com/One-possible-cause-of-accumulating-shibstate-xxx-cookies-td7484042.html

Fixed

Details

Assignee

Reporter

Original estimate

Fix versions

Affects versions

Created April 26, 2012 at 11:58 AM
Updated August 7, 2012 at 12:58 AM
Resolved May 3, 2012 at 4:40 PM