An HTTP cookie (also called web cookie, Internet cookie, browser cookie, or simply cookie) is a small piece of data stored on the user‘s computer by the web browser while browsing a website. Cookies were designed to be a reliable mechanism for websites to remember stateful information (such as items added in the shopping cart in an online store) or to record the user’s browsing activity (including clicking particular buttons, logging in, or recording which pages were visited in the past). They can also be used to remember pieces of information that the user previously entered into form fields, such as names, addresses, passwords, and payment card numbers.
As mentioned above the web browser would send the appropriate cookies for a website in the HTTP header. To do so, the browser follows the same-origin policy to determine which cookies to send when a website is being opened in the web browser of the client. The same-origin policy is also used by the DOM (document object model) to determine if a website can access the domain of another website (for example if a webpage host another site in an IFRAME). But there is a difference on how same-origin policy is understood by the browser DOM and while working with cookies.
Additional attributes of Cookies
Cookies have some additional attributes besides the scheme, domain, port, and path. They are:
- Secure: The “Secure” cookie attribute instructs web browsers to only send the cookie through an encrypted HTTPS (SSL/TLS) connection. It ensures that an attacker cannot simply capture the cookie values from web browser traffic.
- Expires and MaxAge: Sets the expiry date of the cookie, wherein the browser would delete on that date. Marking these fields makes the cookie a persistent cookie, as opposed to a session (temporary) cookie.
- HttpOnly: The “HttpOnly” cookie attribute instructs web browsers not to allow scripts an ability to access the cookies via the DOM document.cookie object. Without this, the cookie is susceptible to be stolen through an XSS.
- SameSite: This allows a server to define a cookie attribute making it impossible to the browser send this cookie along with cross-site requests. The main goal is mitigating the risk of cross-origin information leakage and provides some protection against cross-site request forgery attacks.
So, the scoping attributes of a cookie are the domain and path. So, if two cookies are set by login.site.com with the following attributes –
- Cookie 1: name=userid, value=user1,domain=site.com, path=/,secure
- Cookie 2: name=userid, value=user2,domain=.site.com, path=/,non-secure
When a user accesses the following pages:
- https://account.site.com = Cookie 2 is sent
- http://login.site.com = Cookie 2 is sent
- https://login.site.com = Cookie 1 and Cookie 2 is sent
- http://someothersite.com = No cookies are sent
But keep in mind, the path attribute is for the browser to decide the cookies to send, and not for DOM. So, if there is an XSS vulnerability in the site, the attacker can execute a script in a page of the same domain to read the cookies of all the pages (path) the domain. That is, if a cookie is set by http://site.com/page1.html with the path as page1.html, the script would return cookies for all paths under http://site.com/* (as the path is ignored by DOM).
Few General problems with Cookies
Server Nevers sees anything besides the cookie’s data
That is, the server only sees the Name=Value data, and the browser strips away all attributes of the cookies before sending it through the HTTP header. For example, User1 logins to login.site.com, and the website sets a cookie for *.site.com. Then User1 visit attacker.site.com, which set a new cookie for *.site.com, overwriting the original cookie, with bad data. When User1 visits login.site.com, it gets the attacker cookie, and it has no way of knowing that this is not the original cookie. So, cookies need to be scoped properly to prevent leaking.
Secure cookies are not secure
Suppose, User1 visits an HTTPS version of a website which sets a Secure and HttpOnly cookie. Then the User1 later visits the HTTP version of the website (a lot of websites run as both HTTP and HTTPS), whose traffic is intercepted by an attacker, he injects a Set-Cookie command in the response. This would overwrite the secure cookie, and the server would never know. So, an HTTPS website should never leave an HTTP endpoint accessible. If there is, it is a good idea to redirect to the HTTPS version when someone accesses the HTTP version.
Cookies have no integrity by default
The cookies are stored in the user machine and can be very easily tampered with. Anyone who has access to the machine can delete or edit the contents of the cookies. So, it is imperative to implement a checksum to the cookie. For example, in ASP.Net you can protect the cookie by encrypting it and adding integrity using the System.Web.Configuration.MachineKey.