Content Security Policy (CSP)
Content Security Policy (CSP) lets a site declare which sources the browser may use for scripts, styles, images, frames, connections, and other resources. It reduces the impact of injection vulnerabilities such as cross-site scripting by blocking content that violates the declared policy.
CSP is delivered primarily through the `Content-Security-Policy` HTTP response header. The browser parses the policy and applies its directives to subsequent resource loads and executable content on the protected document.
A policy is composed of directives such as `script-src`, `style-src`, `img-src`, `connect-src`, and `frame-src`. Each directive specifies permitted sources, such as `'self'`, an HTTPS origin, or a nonce. `default-src` provides a fallback for directives that are not explicitly specified.
For inline scripts, a strong policy commonly uses a per-response nonce or a hash instead of allowing `'unsafe-inline'`. A nonce must be unpredictable and must match the nonce placed on the permitted `<script>` element. CSP does not replace output encoding, input validation, or other security controls; it provides an additional browser-enforced layer.
`Content-Security-Policy-Report-Only` can be used to observe violations without blocking the corresponding resources. This is useful when deploying a policy because an overly restrictive CSP can break legitimate application behavior, including dynamically loaded assets and API requests.
CSP is also relevant to frontend architecture: code that depends on arbitrary inline JavaScript, dynamic evaluation such as `eval()`, third-party scripts, or unrestricted network destinations may require redesign or explicit policy allowances. The goal is to specify the narrowest set of capabilities the application actually needs.
Key points
- CSP is a browser-enforced defense against content injection.
- Use explicit directives such as `script-src`, `style-src`, and `connect-src` to control resource classes.
- Prefer nonces or hashes for trusted inline scripts rather than `'unsafe-inline'`.
- `default-src` supplies fallback restrictions for applicable directives.
- Use Report-Only mode to discover violations before enforcing a policy.
Interview questions
What problem does CSP solve, and how does it help against XSS?
CSP gives the browser rules for which resources and executable code a page may use. A restrictive `script-src` can prevent injected scripts from executing when their source or execution mechanism is not authorized. This limits the impact of many XSS scenarios, but it does not make unsafe HTML generation safe by itself. Applications should still use appropriate output encoding and safe DOM APIs.
What is the difference between a nonce and a hash in CSP?
A nonce is a random value generated for a response and attached both to the CSP and to an authorized inline script. A hash authorizes inline script content by including a cryptographic hash of the exact script text in the policy. Nonces are convenient when server-side rendering can generate a fresh value for each response, while hashes can work well for stable inline code. Both are more targeted than permitting arbitrary inline scripts.
What does `default-src` do?
`default-src` provides fallback source restrictions for resource types that do not have their own applicable directive. For example, `default-src 'self'` can establish a same-origin baseline while more specific directives override that baseline for resource categories they govern. It is not a universal replacement for explicitly configuring important directives. Security-sensitive applications should understand which directive controls each resource type.
How would you introduce CSP into an existing frontend application without immediately breaking it?
I would first inventory the application's scripts, styles, images, frames, and network destinations and then deploy a restrictive candidate policy using `Content-Security-Policy-Report-Only`. I would analyze violations, remove unnecessary dependencies, and replace unsafe inline patterns or dynamic evaluation where practical. After testing the required behavior, I would enforce the policy with the narrowest necessary sources and continue monitoring violations. I would also treat third-party scripts as high-impact dependencies because allowing script execution from an origin grants significant trust to that source.
Why can a CSP still be bypassed or provide incomplete XSS protection?
CSP effectiveness depends on the policy being sufficiently restrictive and correctly implemented. Broad trusted origins, unsafe directives, compromised or overly permissive dependencies, and application flaws can reduce its protection. CSP also does not prevent every class of injection or server-side vulnerability. It should therefore complement secure coding, dependency controls, authentication protections, and other security measures rather than serve as the sole XSS defense.