Building

Cookie Prefixes – The Lesser Known Cookie Security Feature

When you’re analyzing web applications as a pentester or reading pentest reports about web applications, you will often see findings regarding cookies missing certain security flags. The Set-Cookie HTTP header and the JavaScript document.cookie API allow to use, for example, the flags SecurePath, and Domain. Common audit and pentest tools will tell you when your web application does not or just insecurely implements these cookie flags.

However, they do not provide optimal security even when using these flags correctly. However, there are mitigations available that partly solve the issues.

Issues with Cookie Security Flags

Let’s examine the cookie security flags and why they may not work as expected.

Secure

The Secure flag seems to be straight forward. It ensures that the cookie value is always only sent via HTTPS (i.e., via encrypted channels). How could this be a problem?

The problem is that the Secure flag only ensures confidentiality at the time of transmission from the client browser to a web server. It does not ensure the integrity of the cookie value because the cookie can still be set via an HTTP connection.

Attackers may not be able to read, e.g., your session cookie, but they may be able to conduct a Man-in-the-Middle attack pretending to be the HTTP version of the targeted web application. The attacker-crafted HTTP response will then contain an attacker-defined Set-Cookie header, for example:

Set-Cookie: SESSIONID=IAMTHEATTACKER; Secure

Even though for the client browser, this Set-Cookie header seems to originate from http://example.com (which is actually attacker-controlled), it will also be sent to the actual https://example.com web application. This may allow the execution of session fixation attacks.

Domain and Path

The Domain and Path flags define the scope of a cookie. The Path flag can scope the cookie to a specific path on a domain. However, the Domain flag can define a wider audience for a cookie than just the specific domain where a web application is hosted.

For the following examples, we assume that our web application, which sets cookies, is hosted on webapp1.example.com.

The first example (no Domain specified) will set a cookie that is only available to web applications hosted on webapp1.example.com:

Set-Cookie: SESSIONID=WEBAPP1; Secure

However, the second example (Domain explicitly set to the domain of our web app) will set a cookie that is available to web applications hosted on webapp1.example.com and all subdomains, for example, dev.webapp1.example.com:

Set-Cookie: SESSIONID=WEBAPP1; Domain=webapp1.example.com; Secure

At last, the third example (Domain explicitly set to our main domain) will set a cookie that is available to web applications hosted on example.com and all of its subdomains, for example, webapp2.example.com:

Set-Cookie: SESSIONID=WEBAPP1; Domain=example.com; Secure

As we can see, a web application can set cookies that are also valid and available to other web applications. Attackers can use this behavior if they find vulnerable web applications hosted under the same domain as a specific targeted web application. They can use it to

  • Read incorrectly scoped cookies of webapp1 on webapp2, or
  • Set a widely scoped cookie on webapp1 whose value will be used on webapp2, for example, to run a session fixation attack against webapp2.

Cookie Prefixes

As shown above, how cookies and their flags are standardized and implemented in modern browsers is not intuitive and has side effects that not everybody would expect.

Modern browsers implement special treatments for two prefixes for cookie names to mitigate the side effects. However, not many developers and pentesters know about them.

Prefix __Secure-

The first prefix is __Secure- (mind the capitalization and hyphen). In contrast to the Secure flag, it ensures confidentiality and integrity. This is because a browser will only set the cookie if

  • The Secure flag is set: the cookie is only sent via HTTPS.
  • The current scheme of the domain that sets the cookie is HTTPS: an insecure / man-in-the-middled HTTP connection cannot set this secure cookie.

For example:

Set-Cookie: __Secure-SESSIONID=MYSESSION; Secure

Both setting and reading the cookie can only be done when HTTPS is in use.

Prefix __Host-

The second prefix is __Host- (mind the capitalization and hyphen). This is even stricter than the __Secure- prefix because, besides communication via HTTPS, it enforces that the cookie is scoped only to the exact domain of the web application. It is set by the browser if:

  • The Secure flag is set: the cookie is only sent via HTTPS.
  • The current scheme of the domain that sets the cookie is HTTPS: an insecure / man-in-the-middled HTTP connection cannot set this secure cookie.
  • The Domain flag is not specified: the cookie is only scoped to the web application’s exact domain, and no subdomains or parent domains can read/set it.
  • The Path flag is set to “/. (However, Firefox does not implement this restriction strictly.)

For example (assuming the cookie is set by webapp1.example.com):

Set-Cookie: __Host-SESSIONID=MYSESSION; Path=/; Secure

Both setting and reading the cookie can only be done when HTTPS is in use. Furthermore, the cookie is only set for and can be read from webapp1.example.com.

Compatibility

Even though you may find browsers that do not support those cookie prefixes, most common modern browsers (Chrome-based and Firefox-based) have been supporting them for quite a time. This means that even if some users of your web application use an exotic browser, most users and their cookies will be protected if your web application uses prefixed cookie names.

Conclusion

Since cookies have to meet particular prerequisites, so you can use prefixes, you may not be able to use prefixes for all of your cookies; especially, if you want to set cookies accessible to other (sub)domains.
For cookies that match the prerequisites, setting prefixes is an easy-to-implement yet widely unknown second layer of defense against certain attack paths. Often, cookie names can be configured easily in configuration files.
However, please remember that – even when using prefixed cookie names – your web application can still have all kinds of vulnerabilities.

Cheers,

Florian

Leave a Reply

Your email address will not be published. Required fields are marked *