actix-web: Cookie parser fails for certain characters

Hey,

I noticed some cookies always appear as None in req.session() (despite being in the Cookie header), depending on what characters are being used apparently. Quick example :

let payload = "hello";

let value = req.session().get::<String>("test");
println!("Value found in headers : {:?}", value); // Ok(Some("hello"))

let res = req.session().set("test", payload);
println!("Set result : {:?}", res); // Ok(())

// send response

Run this a couple times and everything works as expected. Header looks like this :

actix-session=zsf1hIJu4CLUesyWHTQ/pedxPET4eqHjO5AQpvOawMU={"test":"\"hello\""}

Now if I change the payload, this is what happens :

let payload = "FJc%26continue_url%3Dhttp%253A%252F%252Fconnectivitycheck.gstatic.com%252Fgenerate_204"

let value = req.session().get::<String>("test"); 
println!("Value found in headers : {:?}", value); // Ok(None)

let res = req.session().set("test", payload);
println!("Set result : {:?}", res); // Ok(())

Header looks like this :

actix-session=dQxdyG08q5mLMu0Q6KAysLEtYbM/Uak/neM5L3QDj0Y={"test":"\"FJc%26continue_url%3Dhttp%253A%252F%252Fconnectivitycheck.gstatic.com%252Fgenerate_204\""}

It seems like the session middleware never picks up this value for some reason. I assume this is an encoding issue. This happened while storing a URL, my current workaround is to base64 encode the payload and everything works fine.

Any idea what could be causing this ?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (12 by maintainers)

Most upvoted comments

Both cookies shown in the first post are invalid, as you can’t have backslashes in cookie values:

https://tools.ietf.org/html/rfc6265#section-4.1.1 https://tools.ietf.org/html/rfc2616#section-2.2

   cookie-header = "Cookie:" OWS cookie-string OWS
   cookie-string = cookie-pair *( ";" SP cookie-pair )
 cookie-pair       = cookie-name "=" cookie-value
 cookie-name       = token
 cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
 cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
                       ; US-ASCII characters excluding CTLs,
                       ; whitespace DQUOTE, comma, semicolon,
                       ; and backslash
       token          = 1*<any CHAR except CTLs or separators>
       separators     = "(" | ")" | "<" | ">" | "@"
                      | "," | ";" | ":" | "\" | <">
                      | "/" | "[" | "]" | "?" | "="
                      | "{" | "}" | SP | HT
       CTL            = <any US-ASCII control character
                        (octets 0 - 31) and DEL (127)>

Either they should either be magically percent-encoded, or refused by cookie-rs

@DoumanAsh I feel like we’re working around the problem rather than addressing it here.

With your proposed fix, if someone attempts to put some invalid characters in the store (either by inadvertence or simply because they might be unaware of the consequences), then we’re back to square one :p

The way I see it, we can do one of the following things :

  • Keep things as they were, and document the fact that some characters might cause unexpected behavior
  • base64 encode the whole session :
actix-session=UniqueKeyHere={"base":"64","encode":"this"}
                            ^ base64 encode this ------ ^

Option 2 should be pretty straightforward to implement (decode the session payload when a request arrives, encode it before sending the response) and would effectively prevent this sort of things to happen again. Although this should be transparent to most users, it might be considered a breaking change. What do you think of this solution ?