When dealing with Web Application vulnerability assessments, it is very common to come across scenarios where for various reasons (business or otherwise) users decide to focus entirely on Medium or High severity vulnerabilities such as SQL Injection and XML External Entity Injection. As a result, developers and security professionals tend to ignore what are normally considered less severe vulnerabilities such as Source Code Disclosure, Cookies with
Secure flags and so on, thinking that the impact from these vulnerabilities are minimal.
In reality, lower severity vulnerabilities aren’t there to directly exploit a web application. Instead, they act as stepping stones to chain multiple vulnerabilities together and severely increase the overall impact.
The following article illustrates a scenario where misconfigured cookies allowed Stored Cross-site Scripting vulnerabilities injected into an internal test application, to affect all users in a production environment without the attacker having access to production. This was possible despite the cookies having the
Secure flags set to true.
Cookies play a crucial role in the internet as a whole. While notoriously misconfigured in the wild, they allow developers to easily store information into what is generally considered a stateless protocol (HTTP).
This is achieved when a server is responding to a request sent by a client. In this response, the server can optionally embed a special header known as the
Set-Cookie header. In it, the server can specify many properties and “rules”. An example would be:
HTTP/2.0 200 OK content-type: application/json; charset=utf-8 set-cookie: MyCookie=SomeCookieValue; expires=Sat, 09-Feb-2019 16:41:58 GMT; path=/; domain=.example.com;
A few key properties in the
Set-Cookie header to take into consideration:
- Cookie name: MyCookie
- Cookie value: SomeCookieValue
- (Automatic) cookie expiration date in browser : Sat, 09-Feb-2019 16:41:58 GMT
- The path(s) on the web application the cookie can be used on: / – meaning the root of the web application which applies everywhere. If you have multiple applications on a single domain then you can have the path set to a directory such as:
- http://example.com/app1/ – path=/app1
- http://example.com/app2/ – path=/app2
- The domain the cookie is bound to:
.example.comThis is where the problem lies in our scenario. When specifying
.example.comas the domain, you are allowing all subdomains of that domain to access and make use of that cookie, even if they do not explicitly require it.
In this example, we will examine a web application vulnerable to Stored Cross-site Scripting and misconfigured Cookies. The two together allow the attacker to exploit a testing environment and gain production access.
While alarming in itself, some further digging allowed us to force vulnerable users logged into both the testing and production applications to exploit the production environment. This without our intervention and with the same Cross-site Scripting vulnerability.
For this example the production environment resides on http://www.example.com/ and the testing environment resides on http://test.example.com/.
When the user logs into both the Testing and Production environments, the respective servers set their own cookies. To avoid naming conflicts, the developers gave distinct names based on the environment like so:
HTTP/2.0 200 OK content-type: application/json; charset=utf-8 set-cookie: TestCookie=1; domain=.example.com; httpOnly; Secure
HTTP/2.0 200 OK content-type: application/json; charset=utf-8 set-cookie: ProdCookie=2; domain=.example.com; httpOnly; Secure
This means that whenever the user accesses either the production or the testing application, both TestCookie and ProdCookie are sent by the browser. This is because both Cookies are bound to
.example.com rather than their respective sub-domain, like so:
- Set-Cookie: ProdCookie=2; domain=www.example.com
- Set-Cookie: TestCookie=1; domain=test.example.com
The XSS payload would look something along the lines of:
Exploiting Cross-site Scripting in the testing environment isn’t enough to steal production credentials. The reason being that the
To overcome this, the Cross-site Scripting payload embedded in http://evilhost.com/ forces the user to make an HTTP (POST) Request to the production environment with the actual Cross-site Scripting payload used to harvest user passwords. Think of the user as a bridge between testing and production environment.
This can be achieved because the cookies are being scoped to the parent domain (
.example.com) rather than to their respective subdomains. This is often done as a shortcut as it’s much easier to always scope to the parent.
Finally, when the user loads the test application, their browser will send another HTTP request to the production application. This will succeed because the user is authenticating via the
ProdCookie. The result of this request would inject a new payload that sits in the production environment.
This payload could either use social engineering tricks, or simply attach a keylogger to listen in on all the keypresses affected users make!
Always be careful when dealing with Cookies. Ask yourself:
- Does this cookie need to live this long?
- Does this cookie only need to be accessed by part of the web application?
- Do other subdomains need access to this cookie?
With those questions in mind, set the parameters correctly. Always be as strict as you can in the scope and only give access to the cookie where needed. Additionally, always try to keep the
Secure flags set on every cookie.
You may have noticed the elephant in the room—Stored Cross-site Scripting. We go into great detail on how to mitigate such attacks entirely in the following article on Cross-site Scripting (XSS).
Leveraging a Web Application Security Scanner such as Acunetix will greatly increase both the speed and accuracy to which developers and security professionals can detect vulnerabilities. It may also help in detecting weaknesses in the way application Cookies are configured. Allowing users to quickly fix the issues before they are exploited by an attacker.