Recently, I have reported a security issue where a CSRF was used to compromise the integrity of a database stack abusing the web application management tool.
While explaining the issue about the possibility of data modification in the best case and RCE using another CVE in the worst case, I got the comment that it was a total surprise to them to see an CSRF based on the HTTP Authorization header. This instead of the more known form of CSRF, based on a Cookie.
This made me wonder as to whether there are side-effects that authorization based CSRF has. Especially given that legacy systems often connect trough a reverse proxy, which uses HTTP Authorization to quickly protect applications with authentication and authorization.
So, when is the Cookie header evicted? Taken from: RFC 6265, HTTP State Management Mechanism, at The Max-Age Attribute (220.127.116.11)
If a cookie has both the Max-Age and the Expires attribute, the Max- Age attribute has precedence and controls the expiration date of the cookie. If a cookie has neither the Max-Age nor the Expiresattribute, the user agent will retain the cookie until “the current session is over” (as defined by the user agent).
In practice this results in the cookies being evicted on a time and session basis. This possibly limits an CSRF’s success rate due to the user not being logged in at the moment of the attack.
However according to RFC 7235, Hypertext Transfer Protocol (HTTP/1.1): Authentication, works differently.
If a request is authenticated and a realm specified, the same credentials are presumed to be valid for all other requests within this realm (assuming that the authentication scheme itself does not require otherwise, such as credentials that vary according to achallenge value or using synchronized clocks).
Followed by Security Considerations: Authentication Credentials and Idle Clients (6.2)
Existing HTTP clients and user agents typically retain authentication information indefinitely. HTTP does not provide a mechanism for the origin server to direct clients to discard these cached credentials, since the protocol has no awareness of how credentials are obtained or managed by the user agent. The mechanisms for expiring or revoking credentials can be specified as part of an authentication scheme definition.
Now, this is bothersome since: ..1. This affects generally less secure systems with legacy software. CSRF then might be used as a bootstrap for an authenticated attack. ..1. This causes high chances of effective exploitation. After the first login on the origin, the Basic Authorization header will persist, possibly indefinitely.
It is general knowledge that RFCs are not translated literally into browser’s software. This Google Chromium bugreport illustrates the real-world behaviour in modern browsers.
Chrome Version : 10.0.648.133 (Official Build 77742) URLs (if applicable) : Any site that uses HTTP Auth Other browsers tested: Add OK or FAIL after other browsers where you have tested this issue: Safari: FAIL Firefox 3.x: OK (with extension) IE 7⁄8: FAIL What steps will reproduce the problem? 1. Visit a site which uses HTTP Auth. 2. Provide valid credentials. 3. (Optional) Navigate the site for a while. 4. Close the tab. 5. Open a new tab to the same site. What is the expected result? The user will not be logged in. – OR – Between #2 and #3, the browser will offer a user action that clears HTTP Auth credentials. What happens instead? The user is still logged in. The user must restart the browser completely to clear HTTP Auth credentials.
Now, this last comment is very interesting given modern users’ behaviour on laptops; Users don’t close nor restart the browser regularly. Modern operating systems using Standby mode rather than reboots. This behaviour allow for a Basic Authorization header to persist in the background, leaving CSRF open for exploitation.
When the CVE regarding the CSRF vulnerability is public, we will let you know by publishing it on this blog. For any questions, I am available per e-mail at firstname.lastname@example.org.
Happy hacking & disclose responsibly! Ruben