Signed vs. Encrypted: Why Your Cookies Aren't Secret

That Cookie Isn't as Secret as You Think

Hey everyone,

Today I want to talk about a common misconception in web development that can lead to a false sense of security: storing sensitive data in cookies. Many frameworks use what looks like a random, secure string for session cookies, but the reality is quite different.

The problem is that this data is often signed, not encrypted. Let's break down what that means.

Creating Some Common Cookies

To demonstrate, I'll use a small Python script, cookie_maker.py, to generate three common types of "secure" cookies: a JSON Web Token (JWT), a standard ItsDangerous signed cookie (used by Flask), and a timed ItsDangerous cookie.

code.png

After running the script, we get three output files containing what look like random strings. This output looks safe, doesn't it?

cookies.png

Let's examine each one.

1. The JWT Cookie

The JWT standard is widely used for authentication tokens. Our script generated this token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEyMywibmFtZSI6IkFsaWNlIiwiZXhwIjoxNzU1Nzg2NzMzfQ.6p5_BxtyxpR3CNDRd9qianzH4v_qaHWYrsGxwejOrAE

jwt.png

This looks like nonsense, but the first two parts are just Base64 encoded JSON. If we decode them, we see the data in plain text.

2. The ItsDangerous Signed Cookie

This is the type of cookie used by default in the Flask web framework.

eyJyb2xlIjoiYWRtaW4iLCJhY3RpdmUiOnRydWV9.9-vlUrdD9nUTE9jU3A3P9numsjI

sig.png

Again, decoding the first part of this string reveals the data inside.

3. The ItsDangerous Timed Cookie

This is similar to the last one but includes a timestamp to allow for expiration.

eyJ1c2VyIjoiYWxpY2UifQ.aKcf3Q.7PLrsG68Xe1KeNcczxXGI87XkJQ

timed.png

Just like the others, the payload is completely readable.

Signed, Not Encrypted: What's the Difference?

As you can see, anyone can decode the data in these cookies. The "secret" key isn't used to encrypt the data; it's used to create a signature. This signature ensures that if someone tries to tamper with the data (for example, changing "role": "user" to "role": "admin"), the signature will no longer be valid, and the server will reject the cookie.

This is useful for preventing tampering, but it provides zero confidentiality. You should never store any sensitive information like email addresses, permissions, or personal details in these types of cookies, because they can be easily read by anyone who gets ahold of them.

You can find the scripts I used for this demonstration in the Gists below.

As always,
Michael Garcia a.k.a. TheCrazyGM



0
0
0.000
1 comments
avatar

It's still crazy to me that these sorts of things aren't encrypted by default. One thing that I've learned over the years is that our data is never as secure and private as most of us think. 😁 🙏 💚 ✨ 🤙

0
0
0.000