Token Up

Keeping Hands Out of the Cookie Jar

Erin Browning

Slides will be available at:


Erin Browning

Senior Security Engineer

a.k.a., I'm a hacker

You can contact me at:


latacora logo
slack logo

Slack is hiring!

Slack is used by millions of people every day – we need engineers who want to make that experience as secure and enjoyable as possible.

All of the code-blocked URLs are fake.
Please don't attack my website.

I'm going to expand on a point Tony made earlier in his API talk.
At the very end of his talk, he'd listed the Content-Type header as a way to secure your API.
Let's talk about why you'd care.
Certain content types will send cross origin without Cross-Origin Resouce Sharing enabled.
Why is that bad?
By default, cookies are included in requests sent cross domain.
We can't talk about safely sharing resources between domains without talking about SOP.
What is the Same Origin Policy?

Lots of requests can't be made from URL1 to URL2 if they differ on the following things:

  • Protocol (e.g., HTTP vs HTTPS)
  • Port
  • Host

What is CORS?

We care about CORS because of the protection offered by the Same Origin Policy (SOP).

CORS must be set on the assets you are accessing.
How do you even do CSRF protection to your API?
There's an easier way than randomized tokens.
Traditional CSRF protection stores a random token in a form in an HTML page.

That token gets stored on the server as well.

When the form is submitted, the token is sent with the form data and validated on the server.

Your API may be using a CSRF token, or it may just be relying on monolith form CSRF protection--aka, your api may be vulnerable.
Some common Content-Types:
  • multipart/form-data
  • text/plain
  • application/x-www-url-form-encoded
  • application/json
  • application/xml
You can protect from CSRF by dropping any Content-Type your API doesn't consume.
  • multipart/form-data, can go cross origin
  • text/plain, can go cross origin
  • application/x-www-url-form-encoded, can go cross origin
  • application/json, can't go cross origin without CORS
  • application/xml, can't go cross origin without CORS
Problem: How can you drop these legacy formats if you have a monolith on the same TLD as your API that requires these?
First, let's talk about a typical application structure:
  • - contains your frontend + any monolith code
  • - api
  • - administrator site

use subdomains and cookie scoping, a.k.a.,
Now you have:

Scope cookies to www, admin and api instead of using *.

see you on the internet