As a company that is constantly working with our penetration testing clients on understanding where they should focus their efforts, qualifying risk is second-nature to us. On one hand, we never want to undersell a risk, and have a client accept that risk based on an improperly informed position. On the other hand, I think it’s important to look at risks pragmatically, and avoid hyping things into larger issues than they actually are. Over-hyped issues hurt the credibility of information security professionals and distract from the issues that actually matter. They also waste our clients’ limited resources. In the case of a missing security control, we need to be realistic about how much security that control provides in the first place. That’s why I think we should talk about the httponly cookie flag.
So if we go back to the scenario where the httponly flag was supposed to help us, we have 1) a cross-site scripting exploit running malicious script in a victim’s browser, and 2) an httponly session cookie acting as the authentication/authorization token for that use. The attacker cannot read the session cookie. But here are some examples of what the attacker can still do with regards to that application and that session:
- The attacker can read data from the page the victim user is on, and any other page on the same origin (protocol, and full domain or IP, and port). If they wanted to, they could spider the whole application for every piece of data and functionality that user can access, and they could do it all in, for example, a hidden iframe, with no artifacts detectable by the user unless they are monitoring their request traffic.
- The attacker can send requests and read responses from any service in the same origin, or any other service that allows the page’s origin via CORS policy, supplying all cookies the browser has set for the target origin including the session cookie where applicable. This can include target origins that are internal to the victim’s network, as long as the attacker has the inside knowledge or reconnaissance to target them. For example, if the application is at www.badapp.example, and the cookie is scoped to the top of the badapp.example domain, some of the application’s admin functionality uses the internal-api.badapp.example subdomain but accepts the same session cookie for auth, an attacker without direct access to internalapi.badapp.example could still target it through the victim’s browser.
- The attacker can defeat or bypass most forms cross-site request forgery (CSRF) protection, since their exploit is not cross-site, it’s executing in the context of same-site. This also includes the samesite cookie flag, again because the execution context of the payload is the first-party site.
That’s the high-level view. The point is that not being able to retrieve the session cookie might hinder an attacker with a cross-site scripting flaw but a very elementary skillset in web technologies, best case. Your run-of-the-mill web developer will have no trouble working around the limitations the httponly flag imposes.
That’s not to say you shouldn’t use this flag. You absolutely should use it where you can. That’s the best practice. When I perform an application penetration test, my goal is to deliver value in the form of a report that will help you make informed decisions about risks against that application and against your organization. In addition to findings that are directly exploitable, I would point out where breaks from best practices are causing you to needlessly take on additional risk – even if it’s a small amount. I generally include a low risk finding for this issue. But I would say that it should probably never be higher than a low risk, barring highly circumstantial app functionality that would allow it to be exposed without a XSS flaw.