framework: HTTP header field name case-insensitivity is not being respected which leads to improper Session handling.
Overview
Laravel is incorrectly handling HTTP request header field names that are lowercase, which causes the Session handler to improperly issue a new session cookie on every request.
I encountered this bug when working with a NodeJS app configured to proxy requests to Laravel. The HTTP spec is pretty clear that header field names are case-insensitive:
4.2 Message Headers
… Each header field consists of a name followed by a colon ("😊 and the field value. Field names are case-insensitive. …
Reproducing the Bug
Here’s the breakdown of how I tested this and my configuration that lead me to believe the problem exists in the way Laravel parses request headers:
- I have laravel configured to run
php artisan serve --host=127.0.0.1 --port=3000
- I have node running on port 8000, using the npm module
http-proxy
to forward requests to port 3000
To rule out node and http-proxy as a potential source of problems, I first used netcat
to listen on port 3000 (nc -l 3000
) and capture requests that http-proxy
was sending, here’s a dump of what http-proxy
is forwarding to Laravel (note the lower case header field-names):
davidmosher@localhost:~/code/temp/laravel
$ nc -l 3000
GET /auth/csrf_token HTTP/1.1
host: localhost:8000
connection: keep-alive
cache-control: no-cache
pragma: no-cache
accept: application/json, text/javascript
x-requested-with: XMLHttpRequest
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
content-type: application/x-www-form-urlencoded
referer: http://localhost:8000/
accept-encoding: gzip,deflate,sdch
accept-language: en-US,en;q=0.8
cookie: laravel_session=doh0284ujk57ebnldlm2plp795
x-forwarded-for: 127.0.0.1
x-forwarded-port: 53245
x-forwarded-proto: http
When I use telnet 127.0.0.1 3000
in another terminal session I paste the above request that has lowercase header field-names in and receive the following response from Laravel:
HTTP/1.1 200 OK
Connection: close
X-Powered-By: PHP/5.4.14
Set-Cookie: laravel_session=kicg6iu0aobufkl036itar6km6; expires=Thu, 13-Jun-2013 18:48:12 GMT; path=/; HttpOnly
Set-Cookie: laravel_session=kicg6iu0aobufkl036itar6km6; expires=Thu, 13-Jun-2013 18:48:12 GMT; path=/; httponly
Cache-Control: no-cache
Date: Thu, 13 Jun 2013 16:48:12 GMT
Content-Type: application/json
Note the double Set-Cookie
and the laravel_session has a different value than what was sent in the request. If I modify the header keys in my request to uppercase all the words like so:
GET /auth/csrf_token HTTP/1.1
Host: localhost:8000
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: application/json, text/javascript
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:8000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: laravel_session=doh0284ujk57ebnldlm2plp795
X-Forwarded-For: 127.0.0.1
X-Forwarded-Port: 53245
X-Forwarded-Proto: http
Then I get a correct response from Laravel, as follows:
HTTP/1.1 200 OK
Host: localhost:8000
Connection: close
X-Powered-By: PHP/5.4.14
Set-Cookie: laravel_session=doh0284ujk57ebnldlm2plp795; expires=Thu, 13-Jun-2013 18:49:40 GMT; path=/; httponly
Cache-Control: no-cache
Date: Thu, 13 Jun 2013 16:49:40 GMT
Content-Type: application/json
Conclusion
Having ruled out my proxy completely, using netcat and telnet I can only conclude that Laravel is treating http request header field names differently depending on the casing; this causes major problems for anyone setting up a proxy that may use lower case request header field names to forward requests to laravel and expects Session management to work properly.
Is this something that should be fixed by Laravel or at a lower level in Symfony?
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Reactions: 1
- Comments: 35 (20 by maintainers)
FWIW, I dug into Symfony
symfony/http-foundation/Symfony/Component/HttpFoundation/HeaderBag.php
and the code there seems to normalize header keys withstrtolower
, so the problem must exist at another layer.