bare.css is the kind of CSS library that security folks usually like: tiny, boring, and not trying to be a JavaScript framework in disguise.

That changes the CSP conversation quite a bit.

If your site uses bare.css and almost nothing else, you can usually run a very tight policy. If your “simple” site also includes analytics, consent banners, embedded forms, tag managers, and a couple of convenience scripts, your CSP gets messy fast. I’ve seen plenty of “minimal” websites end up with a header that looks like an ad-tech startup wrote it.

So the useful question is not “what is the CSP for bare.css?” Bare.css itself doesn’t need a special policy. The real question is:

How strict can your CSP be when bare.css is part of the stack?

The short answer

If bare.css is self-hosted and your site is mostly static, you can often get away with something close to this:

Content-Security-Policy:
  default-src 'self';
  style-src 'self';
  img-src 'self' data:;
  font-src 'self';
  script-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';

That’s a great baseline. Tight, readable, and easy to reason about.

But if you pull bare.css from a CDN, inject inline styles, or bolt on third-party services, the policy changes. That’s where the tradeoffs show up.

Option 1: Self-host bare.css and keep CSP strict

This is the best setup for most developer sites.

Example

Content-Security-Policy:
  default-src 'self';
  style-src 'self';
  img-src 'self' data:;
  font-src 'self';
  script-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';

Pros

  • Very small attack surface
  • Easy to audit
  • No dependence on third-party CSS hosts
  • Works well with static sites and Hugo
  • No need for unsafe-inline if your templates are clean

If your bare.css file is just a local stylesheet under /css/bare.min.css, this is about as painless as CSP gets.

Cons

  • You need to manage asset hosting yourself
  • Any inline style attributes or <style> blocks may break
  • Third-party widgets will force exceptions later

My bias: self-hosting wins almost every time. CSS frameworks are static assets. There’s rarely a good reason to outsource them to another origin in 2026 unless you really enjoy debugging blocked resources.

Option 2: Use bare.css from a CDN

If you load bare.css from jsDelivr, unpkg, or another CDN, your style-src needs to allow that host.

Example

Content-Security-Policy:
  default-src 'self';
  style-src 'self' https://cdn.jsdelivr.net;
  img-src 'self' data:;
  font-src 'self';
  script-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';

Pros

  • Fast to set up
  • No local asset pipeline needed
  • Fine for prototypes and throwaway demos

Cons

  • Expands trust to a third party
  • Makes policy portability worse
  • CDN changes, redirects, or extra domains can surprise you
  • Harder to lock down long-term

This is acceptable, not ideal. If you’re building a real site, I’d still move bare.css local and remove the extra host from CSP.

Option 3: Allow inline styles for convenience

This is the slippery slope version.

A lot of sites using small CSS libraries still end up with inline style attributes, theme toggles, CMS-rendered blocks, or snippets from plugins. Then somebody adds this:

style-src 'self' 'unsafe-inline';

Example

Content-Security-Policy:
  default-src 'self';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data:;
  font-src 'self';
  script-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';

Pros

  • Fixes a lot of annoying breakage quickly
  • Useful for legacy templates or CMS fragments
  • Easier migration path if you’re tightening CSP gradually

Cons

  • Weakens XSS defenses around style injection
  • Encourages sloppy markup over time
  • Makes it harder to know what your frontend actually depends on

For bare.css specifically, unsafe-inline usually means your app is the problem, not the CSS library. Bare.css doesn’t require it. If you can avoid this, avoid it.

If you need a deeper refresher on why directives like style-src, script-src, and default-src matter, csp-guide.com is a good reference without too much fluff.

Option 4: Strict CSP with nonces and modern script controls

This is where things get interesting if your “simple” site is no longer simple.

A real-world CSP from HeaderTest looks like this:

content-security-policy:
default-src 'self' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com;
script-src 'self' 'nonce-MmQyZTQ5YmItYTlkMy00YjI4LWFkMmUtZjNkNzhlY2VlYWJk' 'strict-dynamic' https://www.googletagmanager.com https://*.cookiebot.com https://*.google-analytics.com;
style-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://*.cookiebot.com https://consent.cookiebot.com;
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.headertest.com https://tallycdn.com https://or.headertest.com wss://or.headertest.com https://*.google-analytics.com https://*.googletagmanager.com https://*.cookiebot.com;
frame-src 'self' https://consentcdn.cookiebot.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
object-src 'none'

This is a good example of how CSP evolves in the real world. The site can still be security-conscious, but once analytics, consent tooling, and external services show up, the header gets broader.

Pros

  • Strong script execution model with nonce-based trust
  • strict-dynamic is much better than giant script allowlists
  • Realistic for production sites with third-party dependencies
  • Keeps dangerous stuff like object-src and framing locked down

Cons

  • More operational complexity
  • Nonce generation has to be correct on every response
  • Harder to understand for teammates
  • Still compromised somewhat by style-src 'unsafe-inline'

For a bare.css site, this level of CSP is usually overkill unless the rest of your stack demands it. The CSS library isn’t what pushes you here. Tag managers and consent platforms do.

Comparison: which CSP style fits bare.css best?

Best security

Self-hosted bare.css + strict allowlist CSP

Use this if your site is mostly static and under your control.

Best convenience

CDN-hosted bare.css + host allowlist

Fine for demos. Not my first choice for production.

Best migration path

Allow unsafe-inline temporarily

Useful when cleaning up templates, but don’t treat it as “done.”

Best for complex production sites

Nonce-based CSP with strict-dynamic

Great when you have dynamic scripts and third-party services. More moving parts, more things to maintain.

If you’re building a Hugo site with bare.css, a small amount of local JavaScript, and maybe a contact form, I’d start here:

Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self';
  img-src 'self' data:;
  font-src 'self';
  connect-src 'self';
  form-action 'self';
  base-uri 'self';
  frame-ancestors 'none';
  object-src 'none';

Then only add directives when the app actually needs them.

If you use an external form backend:

connect-src 'self' https://api.exampleforms.com;
form-action 'self' https://api.exampleforms.com;

If you embed a privacy tool or analytics:

script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com;
img-src 'self' data: https:;

That’s the sane approach: start strict, widen deliberately.

Common mistakes with bare.css and CSP

1. Blaming bare.css for inline style violations

Bare.css is just CSS. If CSP complains about inline styles, check your templates, components, or CMS output first.

2. Using default-src as if it covers everything cleanly

It helps, but explicit directives are clearer. I prefer being specific for script-src, style-src, img-src, and connect-src.

3. Copy-pasting a giant policy from another project

A CSP for a marketing site with GTM, Cookiebot, and analytics is not a good default for a minimal bare.css blog.

4. Forgetting frame-ancestors

If you don’t want your site embedded, say so:

frame-ancestors 'none';

That’s one of the easiest wins in the whole header.

Final take

bare.css is not the hard part. That’s the whole point.

If you keep it self-hosted and avoid inline styling habits, CSP for a bare.css site can be refreshingly strict. That’s rare on the modern web, and worth taking advantage of.

If your site grows extra dependencies, your policy should reflect reality instead of pretending to be pure. I’d rather see an honest CSP with a few justified exceptions than a fake “strict” one that breaks production and gets disabled two days later.

For most bare.css sites, the sweet spot is simple:

  • self-host the stylesheet
  • avoid unsafe-inline
  • lock down scripts hard
  • add third-party origins one by one
  • keep object-src 'none' and frame-ancestors 'none'

That gets you a CSP that is actually maintainable, not just theoretically secure.