CSP or Content Security Policy is a straightforward way to explicitly define what a web page is allowed to do.
In my opinion, it goes hand-in-hand with Feature Policy. Both describe the behavior of the page, but the former focuses on the DOM while the latter governs browser hardware and platform features.
Let's break down each one. Concretely, these are HTTP response headers sent by the server.
As seen in the image, the
Directives like
Take
Another example with
The directive has unsafe in its name for a reason.
Here is a quick overview of directive syntax:
For each directive (script-src, style-src, etc.), you can:
The best rule is simple: start with the strictest policy from day one.
Namely, start with default-src: 'self'.
As the project grows, explicitly allow only what is strictly necessary.
For example, if a library like bootstrap-fileinput injects images directly into the DOM using base64 data URLs, you must explicitly authorize BLOB data:
Feature Policy
Feature Policy applies the same principle to device and browser features. Lock everything down, then enable only what is required:
Key takeaways:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
In my opinion, it goes hand-in-hand with Feature Policy. Both describe the behavior of the page, but the former focuses on the DOM while the latter governs browser hardware and platform features.
Let's break down each one. Concretely, these are HTTP response headers sent by the server.As seen in the image, the
content-security-policy HTTP header contains multiple parts.Directives like
default-src, script-src... describe allowed origins that can be loaded by the browser.Take
script-src as an example. If it contains unsafe-eval, it allows executing JavaScript's eval() function; otherwise, a CSP violation is triggered.Another example with
script-src: if unsafe-inline is specified, inline style attributes can be placed on DOM elements. Otherwise, the browser rejects them. It is generally recommended not to use inline styles and to define styles solely via external stylesheets whose source can be vetted. Furthermore, manipulating CSS attributes dynamically via JavaScript's CSS Object Model will not trigger CSP violations, since they originate from trusted code.The directive has unsafe in its name for a reason.
Here is a quick overview of directive syntax:
For each directive (script-src, style-src, etc.), you can:
- Specify the same origin or subdomain using
'self' - Provide a domain URL without quotes
CSP: base-uriCSP: block-all-mixed-contentCSP: child-srcCSP: connect-srcCSP: default-srcCSP: font-srcCSP: form-actionCSP: frame-ancestorsCSP: frame-srcCSP: img-srcCSP: manifest-srcCSP: media-srcCSP: navigate-toCSP: object-srcCSP: plugin-typesCSP: prefetch-srcCSP: referrerCSP: report-toCSP: report-uriCSP: require-sri-forCSP: sandboxCSP: script-srcCSP: script-src-attrCSP: script-src-elemCSP: style-srcCSP: style-src-attrCSP: style-src-elemCSP: trusted-typesCSP: upgrade-insecure-requestsCSP: worker-src
The best rule is simple: start with the strictest policy from day one.
Namely, start with default-src: 'self'.
As the project grows, explicitly allow only what is strictly necessary.
For example, if a library like bootstrap-fileinput injects images directly into the DOM using base64 data URLs, you must explicitly authorize BLOB data:
media-src: 'self' blob:Feature Policy
Feature Policy applies the same principle to device and browser features. Lock everything down, then enable only what is required:
feature-policy: autoplay 'none'; fullscreen 'none'; layout-animations 'none'; legacy-image-formats 'none'; midi 'none'; navigation-override 'none'; oversized-images 'none'; picture-in-picture 'none'; sync-xhr 'none'; accelerometer 'none'; ambient-light-sensor 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; publickey-credentials-get 'none'; usb 'none'; vr 'none'; wake-lock 'none'; xr-spatial-tracking 'none'; Note that to permit synchronous Ajax, you would set sync-xhr 'self';.Key takeaways:
- Always be as restrictive as possible by default
- Never rely on a single layer of security: CSP is one defense-in-depth mechanism among others
- HTTP headers are crucial: understand their security impact on your application.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
juniko
3 min