Session cookies are often seen as one of the biggest problems for security and privacy with HTTP, yet often times, it’s necessary to utilize it to maintain state in modern web applications. By default, it is insecure and vulnerable to be intercepted by an authorized party.
Cookies typically store session identifiers that may offer full access to an account, therefore if a cookie is intercepted, a session can be hijacked by someone who is not the real user but pretending as that user.
For this reason, it’s very important that we need to set parameters on how the cookies are passed and have it encrypted as they get sent/read between a web server and the browser.
In order to make cookies more secure to use, there are two things we need to pay attention to, they are HttpOnly and Secure flags.
HttpOnly Flag
The first flag we need to set up is HttpOnly flag. By default, when there’s no restriction in place, cookies can be transferred not only by HTTP, but any JavaScript files loaded on a page can also access the cookies. This ability can be dangerous because it makes the page vulnerable to cross-site scripting (XSS) attack.
The only way to restrict this is by setting HttpOnly flag, which means the only way cookies are sent is via HTTP connection, not directly through other means (i.e., JavaScript).
Secure Flag
The second flag we need to pay attention to is Secure flag. This flag highlights the second issue that by default cookies are always sent on both HTTP and HTTPS requests. A malicious attacker who can’t see encrypted traffic with HTTPS connection can easily switch to HTTP connection and access the same cookie because it is not encrypted. Therefore, we need to set the Secure flag to ensure that the cookie in encrypted when it’s created.
Enable HttpOnly Flag in IIS
Edit the web.config file of your web application and add the following:
<system.web> ... <httpCookies httpOnlyCookies="true" requireSSL="true" /> ... </system.web>
Enable Secure Flag in IIS
To enable secure flag in IIS, it is better to use URL Rewrite and add the following to your web.config file:
<system.webServer> <rewrite> <outboundRules> <rule name="Use only secure cookies" preCondition="Unsecured cookie"> <match serverVariable="RESPONSE_SET_COOKIE" pattern=".*" negate="false" /> <action type="Rewrite" value="{R:0}; secure" /> </rule> <preConditions> <preCondition name="Unsecured cookie"> <add input="{RESPONSE_SET_COOKIE}" pattern="." /> <add input="{RESPONSE_SET_COOKIE}" pattern="; secure" negate="true" /> </preCondition> </preConditions> </outboundRules> </rewrite> ... </system.webServer>
Check Flags Settings
This example demonstrates an ASP.NET website that has HttpOnly flag set, but not the Secure flag using a professional web scan tool.
The scanner did not detect secure flag in the HTTP header with the following explanations:
Cookie Missing ‘Secure’ Flag
Description
The session ID does not have the ‘Secure’ attribute set. This attribute prevents cookies from being seen in plaintext. It may be possible for a malicious actor to steal cookie data and perform session theft through man-in-the-middle (MITM) or traffic sniffing attacks. The exploitable condition exists for unencrypted cookies to be passed over the network if a user accesses the site through HTTP instead of HTTPS, or if a link to a resource such as an image file or CSS file within the specified domain uses the HTTP protocol.
Risk
Data may be exposed to unauthorized parties during cookie transmission and increases the risk of session theft via man-in-the-middle (MITM) or traffic sniffing attacks.
Recommendation
Change the default ‘Secure’ attribute from FALSE to TRUE to ensure cookies are sent only via HTTPS. The ‘Secure’ attribute should be set on each cookie to prevent cookies from being observed by malicious actors. Implement the ‘Secure’ attribute when using the Set-Cookie parameter during authenticated sessions.
After applying the recommended configuration mentioned above, the scan result is good as shown below.
As you may have noticed, in this particular example, the Session Cookie Missing ‘HttpOnly’ Flag was already fixed.
Checking the header using cURL:
$ curl -I https://www.itnota.com
Before
HTTP/1.1 200 OK Cache-Control: private, no-store, max-age=0, s-maxage=0 Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Vary: Accept-Encoding Server: Microsoft-IIS/8.5 Set-Cookie: ASP.NET_SessionId=o42zbtr1rzzje3wlvwwcnjmv; path=/; HttpOnly X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000; includeSubDomains; preload X-Frame-Options: SAMEORIGIN Date: Tue, 10 Jul 2018 20:42:03 GMT Content-Length: 6722
After
HTTP/1.1 200 OK Cache-Control: private, no-store, max-age=0, s-maxage=0 Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Vary: Accept-Encoding Server: Microsoft-IIS/8.5 Set-Cookie: ASP.NET_SessionId=bhn5qcmggcxdy34g5d4kp3hk; path=/; HttpOnly; secure X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000; includeSubDomains; preload X-Frame-Options: SAMEORIGIN Date: Tue, 10 Jul 2018 20:46:38 GMT Content-Length: 6722
Notice the word secure after the HttpOnly at the end of the line of Set-Cookie HTTP header.
Emphasis
Set-Cookie: ASP.NET_SessionId=bhn5qcmggcxdy34g5d4kp3hk; path=/; HttpOnly; secure
Buy me a coffee?
If you find this post helpful and would like to buy me a coffee to support the work here, you’ll have our big thanks!
Support IT Nota: Buy me a Coffee
Download
Further Reading
HTTP/2 in Action
The Secure Attribute
The HttpOnly Attribute
httpCookies Element (ASP.NET Settings Schema)
Ensuring secure cookies with URL Rewrite
How to Setup HTTP Strict Transport Security (HSTS) on IIS
Good morning,
just a quick question:
Our WebApp ist behind a set of Loadbalancers, the LB answers to requests via https, the communication between the Loadbalancer and the webserver ist via unsecured http.
The Webserver delivers Session Cookies unsecured. Is it possible to switch ‘Secure’ attribute from FALSE to TRUE even the webserver delivers via http?
Any help apreciated.
Hi Tamer,
Yes, it’s possible. In fact, I did a similar setup a few years back. The secure flag is just to ensure that the cookies are sent via HTTPS to the browser. With that said though, I cannot emphasize to thoroughly test it after implementation.
What service did you use to test your cookies, giving you the “Severity Score” you posted?
Blake,
What’s displayed is a professional tool, but you can achieve the same result with what’s freely available such as https://securityheaders.com.
Since a lot of people set this at the Default Web Site, and there isn’t a web.config file by default, I would also note that you can set this using the Configuration Editor in IIS manager: system.web/httpCookies/httpOnlyCookies.