#auth#infosec

Your Content Security Policy Is Probably Too Loose

· 3 min read

Every codebase has one area everyone is a little afraid to touch. On our team, it was everything related to content security policy.

Most of the complexity was accidental. Over the years we'd layered three different approaches to content security policy on top of each other, and each one made sense at the time.

Some background

The first symptom was subtle. Nothing failed outright, but content security policy kept drifting in the wrong direction, and every fix seemed to make the next one harder.

The setup was ordinary: OpenSSL at the edges, Sigstore doing most of the heavy lifting, and a handful of scripts nobody wanted to own. It worked well until usage roughly doubled over a single quarter.

A simpler approach

The key insight was to treat content security policy as part of the interface rather than an implementation detail. Once we did that, most of the other decisions followed naturally.

Here's a trimmed-down version of what we ended up with:

Content-Security-Policy: default-src 'self';
  script-src 'self' 'nonce-r4nd0m';
  style-src 'self';
  img-src 'self' data:;
  frame-ancestors 'none';
  base-uri 'self'

This alone let us delete a surprising amount of code elsewhere in the project.

A few things that helped along the way:

  • Make the default the safe choice, not just the documented one.
  • Delete dead code aggressively; it's the cheapest refactor there is.
  • Write the migration guide before writing the migration.
  • Keep the old path around until the new one has survived a real incident.

Trade-offs

None of this is free. The new approach is a bit more verbose, and newcomers occasionally ask why we don't just use Wireshark for everything. That's a fair question with a boring answer: we tried, and it made content security policy harder to reason about.

The biggest cost was social, not technical. Changing how people think about content security policy takes much longer than changing the code.

Takeaways

That's it for now. Next time I'll dig into SSRF, which turned out to be closely related.

RK
Rafael Keller
Security engineer in Brisbane. Writing about application security.