We’re talking about HTTP cookies, which are small text files stored on your computer by websites to keep track of your preferences and other information. And in this guide, we’ll be diving into how they work and implementing them using Python!
To kick things off what exactly is an HTTP cookie? Well, it’s a piece of data that gets sent from the server to your browser when you visit a website. This data can include things like your login information or preferences for certain settings on the site. The next time you visit that same site, your browser sends this data back to the server so that it knows who you are and what you want.
Now, how we can implement HTTP cookies using Python. We’re going to use a module called `http.cookies` which is part of the standard library in Python 3. This module provides classes for abstracting away parsing and formatting HTTP cookies.
First, let’s create a simple web server that sets a cookie on your browser when you visit it:
import http.server
from http.cookies import SimpleCookie
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write("Welcome to my website!".encode())
# Set a cookie with the name "mycookie" and value "hello world"
c = SimpleCookie()
c["mycookie"] = "hello world"
c.setpath("/") # set the path for this cookie so it's sent on all requests to our site
self.send_header("Set-Cookie", str(c).encode())
def do_HEAD(self):
self.do_GET()
http.server.HTTPServer(('', 80), MyHandler)
In this example, we’re using the `SimpleCookie` class to create a new cookie with the name “mycookie” and value “hello world”. We also set its path to “/”, which means it will be sent on all requests to our site.
Now let’s test out our web server by visiting http://localhost:80 in your browser. You should see a message that says “Welcome to my website!” and the cookie should be set automatically!
But what if we want to do something more complex with cookies? Maybe we want to store some data on the client’s computer for future use, or maybe we want to restrict certain domains from setting cookies. Well, Python has got you covered there too!
Let’s say we have a web application that uses RFC 2965 cookies (which are more secure than regular cookies) and blocks some domains from setting cookies:
import urllib.request
from http.cookiejar import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(rfc2965=True, strict_ns_domain=Policy.DomainStrict, blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
In this example, we’re using the `CookieJar` class to create a new cookie jar with some custom policies. We set the policy to use RFC 2965 cookies (which are more secure) and block any domains that contain “ads” in them from setting cookies.
Now how we can verify the authenticity of HTTP cookies using Python. This is important for preventing attacks like cross-site scripting (XSS) and session hijacking, which can be used to steal sensitive information or take control of your computer.
To do this, we’re going to use a technique called HMAC signing. Here’s an example:
from hashlib import blake2b
from hmac import compare_digest
import base64
def sign(cookie):
key = b"my secret key" # replace this with your own server-side secret key!
digest_size = 16
hasher = blake2b(digest_size=digest_size, key=key)
hasher.update(cookie)
return base64.b64encode(hasher.hexdigest().encode("utf-8")).decode()
def verify(cookie, sig):
if not isinstance(sig, str):
raise TypeError("Signature must be a string!")
key = b"my secret key" # replace this with your own server-side secret key!
digest_size = 16
hasher = blake2b(digest_size=digest_size, key=key)
hasher.update(cookie)
calculated_sig = base64.b64encode(hasher.hexdigest().encode("utf-8")).decode()
return compare_digest(calculated_sig, sig)
In this example, we’re using the `blake2b` hash function to generate a HMAC signature for our cookie. We first create a new hasher object with a secret key and then update it with the contents of the cookie. Finally, we convert the resulting hexadecimal digest into a base64-encoded string which can be sent over HTTP as part of the cookie header.
To verify this signature on the server side, we simply calculate the same HMAC signature using our secret key and compare it to the one that was sent by the client. If they match, then we know that the cookie hasn’t been tampered with!