Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Per response from [email protected] posting as public PR. Proof of concept to demonstrate the vulnerability can be seen at https://github.com/security-curious/cookie-prefix-crystal-poc
Crystal automatically encodes and decodes cookie names. The cookie spec encourages the value to be encoded but says nothing about the cookie name (it could be encoded or not).
While encoding is allowed, a vulnerability can occur if the cookie name is decoded in such a way that a cookie not using a correctly formed cookie prefix will overwrite a cookie that is using a proper cookie prefix rendering the protections provided cookie prefixes void.
Since Crystal is encoding the entire cookie name using URL encoding two cookies can be sent by the browser and if in the correct order the server will read the cookie without the proper cookie prefix. An example cookie header value is:
The exact same issue was recently corrected in the
rack
library for the Ruby language as well as thewerkzeug
library used by Python's Flask web framework. In fact those corrects are what prompted me to look to see if Crystal had the same issue.Although NIST rated the Rack vulnerability "high" the Rack maintainers consider that a mistake and consider is a low priority vulnerability. I agree.
The solution taken by both
rack
andwerkzeug
were to simply stop encoding the cookie name. If an application needs it encoded because they have a funky name that might mess with header parsing that application can do the encoding itself. This is the solution implemented on this commit.An alternative solution that is probably more compatible but also more complex is to encode the part of the cookie name after
the cookie prefix if the cookie has a prefix that matches one of the official cookie prefixes (
__Secure-
and__Host-
).While this would preserve the encoding for the most part I don't feel the complexity introduced is worth the benefit.