Content Security Policy
A Content Security Policy (CSP) regulates loading external resources. It allows developers to set restrictions on loading JavaScript, CSS, and other resources.
It is a good practice to set a baseline policy of default-src 'self' (which allows only resources originating from the current origin to be loaded — “Only load your own content”), and then to allowlist any additional resources which should be allowed. Allowlisting can be done by resource type or origination location. (Note: CSP’s 'self' source expression is distinct from the browser’s Same-Origin Policy, which is a separate browser security model.)
CSP directives are sent to the browser in the response header. The response header can be configured in the application or as a default in the web server configuration.
Example:
CSP directives which allowlist current page, Google APIs, and a Facebook embedded iframe.
default-src 'self';
script-src 'self' https://apis.google.com;
frame-src https://*.facebook.com
Note that a host-source without a wildcard matches only that exact host — https://facebook.com would not permit an iframe served from www.facebook.com. Per MDN’s host-source matching rules, a wildcard such as https://*.facebook.com permits resources from any subdomain of facebook.com (though not from the bare apex domain itself).
A policy built from host allowlists like the one above is a location-based (or allowlist) CSP. For controlling scripts as a mitigation against Cross-Site Scripting (XSS), MDN’s CSP guide recommends a strict CSP that uses nonce- or hash-based script-src directives instead, because allowlist CSPs are hard to get right, often inadvertently allow unsafe domains, and can grow very large when they cover scripts outside your control. With a nonce, the server generates a new, unpredictable random value for every HTTP response, puts it in the policy, and sets the same value as the nonce attribute on each <script> element it intends to include:
script-src 'nonce-{RANDOM}';
object-src 'none';
base-uri 'none';
A hash-based policy (script-src 'sha256-{HASHED_SCRIPT}') suits pages that cannot be generated dynamically, but the hash must be recalculated whenever the script contents change.
Note: prefer the more specific frame-src (for <frame>/<iframe>) and worker-src (for web workers) directives over child-src. CSP Level 3 un-deprecated frame-src; child-src remains valid but is the broader, less specific option (MDN: CSP child-src).
It is also a good idea to add frame-ancestors 'none' (or a strict allow-list) to prevent your own pages from being embedded in another site’s iframe — this is the modern, CSP-based replacement for the X-Frame-Options response header and is the recommended clickjacking defense (OWASP Clickjacking Defense Cheat Sheet).
An allowlist entry such as https://apis.google.com trusts whatever that host serves, so CSP alone cannot help if a third-party host such as a CDN is compromised and starts serving malicious code. Subresource Integrity (SRI) checks the content itself: the integrity attribute on a <script> element (or a stylesheet <link> element) carries a base64-encoded cryptographic hash prefixed with its algorithm (sha256, sha384, or sha512), and the browser refuses to load the resource if its contents do not match. Cross-origin requests that use SRI must use CORS, so the element needs a crossorigin attribute and the host must send an Access-Control-Allow-Origin header:
<script
src="https://cdn.example.com/library.js"
integrity="sha384-{BASE64_HASH}"
crossorigin="anonymous"></script>
The hash can be generated with OpenSSL, for example cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A, and must be regenerated whenever the file changes. The newer Integrity-Policy response header lets a site require integrity metadata on scripts and stylesheets, but MDN lists it as limited availability (not yet supported in some widely used browsers).