Cookies Visualized: Everything you ever need to know about Web Cookies

Skrew Everything
From The Scratch
Published in
11 min readDec 1, 2020

Web Cookies are more or less like a child 👶. Most of the time, they both are harmless.

But once you don’t give enough attention and leave cookies alone, they can bring down even the most secure websites. By the time you realize, your website is compromised and burned to the ground.

Never leave a child alone

Never think web cookies (or kids) are harmless. Give maximum attention for your better future!

The most confusing things about the cookies are—

  1. When they are sent
  2. When they are not sent
  3. To which domains they are sent
  4. How cookies work for cross-domain requests

Let me put an end to all these by visualizing how cookies work in the wild!

The basics of a cookie —

When you first visit a website that you have never visited, the browser doesn’t have any cookies associated with that website.

  1. So, the initial request doesn’t have any cookies.
  2. Then in the response from the server, a cookie is sent to the browser. The browser saves this received cookie for future requests.
  3. From now onwards, whenever the client makes a request, the browser attaches the saved cookies and sends it to the server

This is how the basic concept of cookies work.

There are many important things that most of you don’t realize —

FYI, Cookies are a feature of the browser. For server, it is just a normal header.

The browser takes care of storing and attaching cookies based on the domain(we will come to this) and the expiration time.

If you are familiar with cURL, you might remember that handling of cookies(storing from the response and attaching to the request) must be done by the user by using -c flag.

From cURL man pages:

-c, — cookie-jar <filename>
(HTTP) Specify to which file you want curl to write all cookies after a completed operation. Curl writes all cookies from its in-memory cookie stor-
age to the given file at the end of operations. If no cookies are known, no data will be written. The file will be written using the Netscape cookie
file format. If you set the file name to a single dash, “-”, the cookies will be written to stdout.

This command line option will activate the cookie engine that makes curl record and use cookies. Another way to activate it is to use the -b,
— cookie option.

If the cookie jar can’t be created or written to, the whole curl operation won’t fail or even report an error clearly. Using -v, — verbose will get
a warning displayed, but that is the only visible feedback you get about this possibly lethal situation.

If this option is used several times, the last specified file name will be used.

Also, if you observe the request and response headers for a cookie, you will see that not all the information is sent to the server. Only the name and value of the cookies are sent.

In request headers, only the cookie’s name and value are sent

This is because, the browser is responsible for managing cookies, and the cookie’s attributes like domain, path, secure, httponly, and expiration time help the browser manage its store of cookies. Therefore, although you can read the name and value of a cookie, you cannot read the cookie’s other attributes(through javascript on the client-side). And also when the browser sends the cookie information to the server, the browser only includes the name and value.

Cookies are always sent to the domain(or sub-domains) that it was created by!

This is the most important rule the cookies follow —

No matter what, the cookies are only sent to the domain it was set by, even during cross-origin requests, PERIOD.

If your browser is making two requests for two different domains, then —

Cookies are sent to their respective domains only.

The below scenario is not possible.

Again, to be clear, cookies set by A-DOMAIN.COM will never be sent to B-DOMAIN.COM

This is a major security feature that prevents cookies to be read by other domains. This is necessary because cookies are used for Sessions(to store the sessionID of the user). If this is allowed then it leads to Session Hijacking.

For those of you who don’t know what a Session Hijacking means, the attacker steals the session cookie to pose as the victim without needing to authenticate(without entering/knowing the victim’s password).

Session Hijacking is just one possible threat. Not the only one though.

The server can only set cookies for its own domain —

The thing with the cookies is, the browser only accepts the cookies with the domain name attribute with the same value as the domain name it was sent from.

That means facebook.com can only set cookies for facebook.com.

If google.com tries to set cookies for facebook.com by providing Domain=facebook.com in the Set-Cookie header, then the cookie is rejected by the browser —

Till here, I hope the concepts are clear. If not, make sure you understand them clearly because the whole thing gets complicated as soon as sub-domains are introduced.

Domain Matching

The most confusing thing about cookies is how to share and not to share cookies between your sub-domains

Before getting down the rabbit hole, memorize the below anatomy.

We also need to know how domain matching works in the browsers.

Domain matching is used to decide whether the browser should accept or reject a cookie with a particular domain attribute in response and which cookies need to be sent while performing a request.

The domain matching test always tries to match the suffix of the host name with the domain attribute. If the domain attribute is present in the host name as the suffix, then the domain matching test is passed and cookies are sent(in request) and cookies are accepted(in response).

Another important detail about cookies that most people don’t know is —

Cookies are not affected by Port numbers.

Cookies can work even for IP Addresses as host name.

Below example table shows which domains are accepted and rejected for domain attribute for example.com host in a browser response —

Below example table shows to which hostnames which cookies are sent with a particular domain attribute for a request —

First, let's see how to share cookies —

To share cookies between sub-domains and second-level domains, domain attribute must be set.

Parent domain can set cookies which can be used by sub-domains

If the parent domain sets cookies using a domain attribute then the cookies can be accessed by all of its sub-domains.

Sub-domains can set cookies not to share it with the parent domains but can be shared with its relative subdomains

If a sub-domain(x.example.com) sets a cookie using the domainattribute with the sub-domains hostname(x.example.com), then the parent domain(example.com) cannot access it. But, the sub-domains(y.x.example.com) of it can access it as it becomes parent(x.example.com) to other relative subdomains(like y.x.example.com, z.y.x.example.com, zy.x.example.com etc).

Now, How not to share cookies using HostOnly Cookies

Sharing cookies is not always desired. Sometimes, a particular cookie must be made available exclusively to the host to which it set the cookie.

This can be achieved by not mention anything in the domain attribute in the Set-Cookie header. This makes the cookie hostOnly , which means the cookie is only available to the host it created.

How Secure Flag works in Cookies

Secure flag in Cookies can be used to only transfer the cookies if and only if the connection is Secure ie., over HTTPS. If the connection is not secure, then no cookies are transferred between the client(browser) and the server.

This can help to prevent Man In Middle Attacks in which, a person reads/modifies the unsecured content while transferring between two people without their knowledge.

From Wikipedia:

Secure cookie

A secure cookie can only be transmitted over an encrypted connection (i.e. HTTPS). They cannot be transmitted over unencrypted connections (i.e. HTTP). This makes the cookie less likely to be exposed to cookie theft via eavesdropping. A cookie is made secure by adding the Secure flag to the cookie.

If the connection is not Secure i.e., over HTTP, then the cookie is not accepted(or not sent to the server.)

If the connection is Secure i.e., over HTTPS, then the cookie is accepted(or sent to the server.)

How HTTPOnly Flag works in Cookies

If the httpOnly flag is enabled on a cookie, then it is not accessible to client Javascript.

This is useful when you don’t want anyone to read/modify the cookie on the client-side. For example, a user session cookie doesn’t need to be available for reading and modifying on the client-side.

From Wikipedia:

Http-only cookie

An http-only cookie cannot be accessed by client-side APIs, such as JavaScript. This restriction eliminates the threat of cookie theft via cross-site scripting (XSS). However, the cookie remains vulnerable to cross-site tracing (XST) and cross-site request forgery (CSRF) attacks. A cookie is given this characteristic by adding the HttpOnly flag to the cookie.

How Session Cookies work

Every cookie can be provided with an expiration DateTime either using maxAge or expires attribute. After the expiration DateTime, the cookie gets invalidated/removed from the browser.

But if no value is provided for maxAge or expires attribute, then the cookie is said to be a session cookie.

From Wikipedia:

Session cookie

A session cookie, also known as an in-memory cookie, transient cookie or non-persistent cookie, exists only in temporary memory while the user navigates the website. Web browsers normally delete session cookies when the user closes the browser. Unlike other cookies, session cookies do not have an expiration date assigned to them, which is how the browser knows to treat them as session cookies.

As there is no expiration datetime is mentioned for a session cookie while creating it, the browser deletes this cookie when the browser window(not a tab) is closed/quit.

Cookie behavior in Ajax Requests

While making ajax requests, we can choose whether to send cookies are not using credentials property.

credentials has 3 values:

  1. omit
  2. include
  3. same-origin

You can send requests to either to the same origin or cross-origin using ajax.

Same-origin requests

Same-origin requests are when you make an ajax request to the same hostname displayed in the address bar of a browser.

credentials: 'omit'

While making the request, the browser doesn’t send any cookies to the server.

This option means “don’t send any cookies in the request”.

credentials: 'same-origin'

While making the request, the browser sends available cookies to the server.

This option means that “send the cookies if and only if the request is to the same origin”.

credentials: 'include'

While making the request, the browser sends available cookies to the server.

This option means “send the cookies with the request”.

Cross-origin requests

Cross-origin requests are when you make an ajax request to a server that has a different hostname from what is displayed in the address bar of a browser.

I have seen many people thinking that in cross-origin requests, cookies from different origins are also sent, which is completely wrong!

The above rules still hold, even for cross-origin requests! Again, this is never possible —

All the rules about domain matching still hold in cross-origin requests.

credentials: 'omit'

While making the request, the browser doesn’t send any cookies to the server.

This option means “don’t send any cookies in the request”.

credentials: 'same-origin'

While making the request, the browser doesn’t send any cookies to the server.

This option means that “send the cookies if and only if the request is to the same origin”.

credentials: 'include'

While making the request, the browser sends available cookies to the server.

This option means “send the cookies with the request”.

To make the above thing easy, remember this matrix:

So, go ahead and bookmark it, and don’t be selfish! Share it with fellow developers to help them out

Want to contact me? Twitter.com/@SkrewEverything.

Found any mistakes or got anything to say? Comment down below.

Liked it? 👏👏👏 it and Share it.

References

--

--

Skrew Everything
From The Scratch

A wannabe artist 👨‍🎨, but can’t draw 😫. A wannabe athlete 🏃‍♂️,but can’t run 🥵.Found my peace with coding 👨‍💻 and writing ✍️. Twitter.com/SkrewEverything