SOU✌️IKINATOR

Know The Web: HTTP Cookie 🍪


cookies-banner.png

In this post we are going to learn about Cookie certainly not the edible one. We’ll discuss about cookie properties and security stuff related to cookie. We’ll also create cookie on the way so make sure that you and your patience grab milk and cookie, enjoy the post.

While using Facebook, Instagram or any other services online did you notice that once you logged into these services you don’t have to login when you visit these site again. You searched for shoes and the next moment when you visit to any site, you get to see ads related to shoes.

How the hell all that happens? Is there some mind reading stuff going on?

sorcery

To define, cookie are small chunks of temporary data (key value pair) in the browser which helps in various functionalities in any web services (as mentioned above). These web services/websites setup cookie into your browser and use for features like managing you session on their service/website, to track you and stuff like that. They can also be used to remember pieces of information that the user previously entered into form fields, such as names, addresses, passwords(not a good idea😅), and payment card numbers.

Now as these websites/web services are able to access the cookie they places in your browser which is makes it clear that, “every time you make a request to the website/web service, the cookie is sent to the server along with the request”.

🕵️‍♂️ Sherlock mode ON!

Let’s head over to a random site and have a look at their cookies. On the way I’ll explain about the properties.So I am heading to motherfuckingwebsite.com. In developer tools open the Application tab and then to cookie > https://mothe…. There you get to see following:

cookies-application.png

Those with green underline are options. Name & Value are self explanatory. The rest are what we need to understand.

Each cookie has a domain pattern to which it belongs and can only be accessed by that specific domain pattern.

If cookie named cookie-1 is added for .motherfuckingwebsite.com (notice the .) then cookie-1 can be accessed by any subdomain of motherfuckingwebsite.com. Example: cookie-1 can be accessed by the domain motherfuckingwebsite.com as well as it’s subdomain like www.motherfuckingwebsite.com or www2.motherfuckingwebsite.com and so on.

If cookie named cookie-2 is added for a subdomain xyz.motherfuckingwebsite.com then it can be only accessed by its subdomain and itself. Example: cookie-2 can be accessed by subdomain xyz.motherfuckingwebsite.com and it’s subdomain abc.xyz.motherfuckingwebsite.com.

you can read more at RFC2109

Suppose you want to make a cookie accessible to a specific path then this option is used. Refer below for explanation with examples.

As I have mentioned right in the start that “cookies are temporary data” i.e they have a validity duration after which they expire. How is validity duration determined? By the web service/website. Whenever a website/web service creates a cookie, it also mentions its life time.

HttpOnly, Secure and SameSite will be explained in the security section.

Okay! enough talks. Let’s create some cookie, heat up your oven (browser) and head over to the ingredients 😅.

👨‍💻 The Client Way

First we’ll discuss about creating cookie from the client side i.e from the browser using JS which is pretty easy.

document.cookie

How about having a look at existing cookie using JS? Just use document.cookie in the console and you’ll see following:

cookies-console.png

Notice, each cookie is separated by semicolon(;).

document.cookie="itsME=1"

NOTE: Above code doesn’t override cookie. It only created a new one.

cookie-bake.png

You can see it’s defined for domain motherfuckingwebsite.com now as per the properties we have discussed above, www.motherfuckingwebsite.com should not be able to access the cookie itsME.

cookie-subdomain.png

and we don’t see the cookie that we created hence our verified the properties. You can also try for other example I have mentioned above on you own.

How about adding Path option to our cookie? Let’s go…

document.cookie="itsMe=7; path=/test";

The above code will only set cookie for motherfuckingwebsite.com/test and can only be accessed by it. Here is the example.

document.cookie="itsME=7; path=/test";

cookie-path.png

Image 1: we are accessing cookie from motherfuckingwebsite.com and there is no such cookie.

Image 2: we are accessing cookie from motherfuckingwebsite.com/test and we can see it.

Let’s create a cookie with a expiry date. Now we can do this in two ways.

  1. Expires: Takes date as value.
//86400e3 is same as 86400000 i.e 24 hours in milliseconds
var exp_date=new Date(Date.now()+86400e3);
//refer template literals in JS if not familiar with ${}
document.cookie=`itsME2=2;expires=${exp_date.toGMTString()}`; 
  1. Max-age: Takes time (in seconds) as value.
//86400 i.e 24 hours in seconds
document.cookie=`itsME3=3;max-age=86400`; 

Above we have created both the cookie with validity of 24 hrs. from the time the cookie were created.Here you can compare all three cookie we have set so far.

cookie-expire.png

Notice! in the Expires/Max-age part you can see ItsME2 and ItsME3 has some date and time but ItsME shows session. It is so because when you don’t mention any expiry time of cookie then browser considers it as sessional cookie and it expires as soon as you close the browser. Go ahead, give it a try.

💡 Head over to didthanoskill.me and look for cookie from the URL bar. You’ll see 1 cookie in use. When you do document.cookie in browser console, empty string is returned which is weird. Go to Application tab in developer tool and there also you’ll see no cookie. Any idea why is so? Hint: have a look at the source and if still don’t understand then run debugger in the dev tool to understand why is it happening so?

🖥️ The Server Way

We saw the client Way of creating cookie. Now we’ll create cookie from server side and I’ll use NodeJS and express for this.

Basically what happens is when the client makes a request to the server, the server responds with a response which contains header and in that header there is set-cookie option which tells browser to create cookie.

const app=require("express")();
app.get("/",(req,res)=>{
    //setting response header
    res.setHeader("set-cookie",["itsSERVER1=h1"]); 
    res.send("this is https://localhost:2000/");
});

app.listen(2000,()=>{
    console.log(">2000<");
})

and we have it.

const app=require("express")();
app.get("/",(req,res)=>{
    /*can also use res.setHeader() instead of
    res.cookie()*/
    res.cookie("itsSERVER1","h1");
    //for path /hahahayes
    res.cookie("itsSERVER2","yeet!",{path:"/hahahayes"});  
    res.send("this is https://localhost:2000/");
});

app.get("/hahahayes",(req,res)=>{
    res.send("this is https://localhost:2000/hahahayes");
});

app.listen(2000,()=>{
    console.log(">2000<");
});

gives following result:

cookie-ss-path.png

cookie-ss-path2.png

so on and so forth for other options as well.

🔒 Security

Security is a very important topic of discussion over here. As mentioned earlier, services like social media use various cookie to keep you logged in. If such cookie get in hands of attackers they can easily break into your account and rest you know.

When user privacy is a concern, it’s important that any web app implementation invalidate cookie data after a certain timeout instead of relying on the browser to do it.

If you are using cookie to store some data and later rendering it in DOM (which is a super duper bad practice) then make sure to keep the valid formatting, they should be escaped using a built-in encodeURIComponent function:

var cookie_name="mycookie";
var cookie_value="myvalue";
document.cookie = `${encodeURIComponent(cookie_name)}=${encodeURIComponent(cookie_value)}`;

In section The Client Way, we easily accessed the website’s cookie using JavaScript, so a attacker may find a vulnerability like XSS which enables them to execute malicious JS code on the website and bypass logins. It’s really hard to keep track of XSS especially in humongous applications from a developer point of view. Due to this some security features are there in cookie, which prevent such attacks even if the attacker is able to execute some code.

You can check out Hack this site basic 10 which demonstrates, what careless use of cookie can lead to.

HttpOnly is an option used by web-server when they set cookie. This option forbids any JavaScript access to the cookie. This is a precaution measure, to protect from certain attacks.

//server side
const app=require("express")();
app.get("/",(req,res)=>{
    /*can also use res.setHeader() instead of
    res.cookie()*/
    res.cookie("itsSERVERsecure","100",{httpOnly:true});  
    res.send("this is https://localhost:2000/");
});

app.listen(2000,()=>{
    console.log(">2000<");
});

and you’ll se a tick mark (✔️) under HttpOnly in Application tab (developer tools). Try accessing it using JS.

If your cookie contain sensitive content then you may wanna send it over HTTPS. To accomplish this you have to include secure option as shown below.

//client side
document.cookie = "ItsMeSecure=6; secure";
//server side
const app=require("express")();
app.get("/",(req,res)=>{
    /*can also use res.setHeader() instead of
    res.cookie()*/
    res.cookie("itsSERVERsecure","100",{secure:true});  
    res.send("this is https://localhost:2000/");
});

app.listen(2000,()=>{
    console.log(">2000<");
});

samesite SameSite prevents the browser from sending the cookie along with cross-site requests. Possible values are lax, strict or none.

The lax value will send the cookie for all same-site requests and top-level navigation GET requests. This is sufficient for user tracking, but it will prevent many CSRF attacks. This is the default value in modern browsers.

The strict value will prevent the cookie from being sent by the browser to the target site in all cross-site browsing contexts, even when following a regular link.

The none value explicitly states no restrictions will be applied. The cookie will be sent in all requests—both cross-site and same-site.

So make sure that you use cookie wisely 🦉. Feel free to point out any issue in the code or content.



🥳 So it’s time to wrap up the post with a quote

“Opportunities don’t happen. You create them” -Chris Grosser


          Souvik Kar Mahapatra's DEV Community Profile


#know the web #http cookie #cookie