[Blog](/blog)

Show links

Resources

[Blog](/blog)

[Breaches](/breaches)

[eBooks, reports, & more](/resources)

[Events](/events)

[News](/news)

[Risks and Vulnerabilities](/category/risks-and-vulnerabilities)

Show links

Categories

[Attack Surface Management](/category/attack-surface-management)

[Company News](/category/company-news)

[Compliance and Regulations](/category/compliance-and-regulations)

[Cybersecurity](/category/cybersecurity)

[Data Breaches](/category/data-breaches)

[DevOps](/category/devops)

[Human Cyber Risk](/category/human-cyber-risk)

[Risks and Vulnerabilities](/category/risks-and-vulnerabilities)

[Third-Party Risk Management](/category/third-party-risk-management)

[Vendor Risk Management](/category/vendor-risk-management)

[What is a Content Security Policy (CSP)?](/blog/content-security-policy)

Publish date

October 13, 2026

{x} minute read

# What is a Content Security Policy (CSP)?

[Get a demo](/contact-sales)

[Free trial](/demo)

[Download the PDF guide](/resources/complete-guide-to-data-breaches)

[Free trial](/demo)

Written by

[Caitlin Postal](/team/caitlin-postal)

Technical Writer

Reviewed by

[Phil Ross](/team/phil-ross)

Chief Information Security Officer

Phil is a Forrester Zero Trust Strategist leveraging decades of experience in enterprise cybersecurity architectures.

Table of contents

eBook

A Complete Guide to Data Breaches

Free resource

### A Complete Guide to Data Breaches

Learn how to avoid a costly data breach with a comprehensive prevention strategy.

[Download now](/resources/complete-guide-to-data-breaches)

Every website needs to be set up with a cloud service provider, but what about your other CSP: Content Security Policy?

The Content Security Policy (CSP) is a standard provided in an HTTP response header that helps prevent [cross-site scripting attacks (XSS)](https://www.upguard.com/blog/cross-site-scripting-xss), [clickjacking](https://www.upguard.com/blog/what-is-clickjacking), packet sniffing, and malicious content injection on the client side of your web page. Configuring the \[.rt-script]Content-Security-Policy\[.rt-script] header will enable a CSP with the directives you supply to control how a user agent loads resources on your site. This post provides details about how a Content Security Policy works, how to configure your CSP, and common issues with CSP setup.

## What is a Content Security Policy?

While input validation and output encoding are the first line of defense against code injection attacks, your Content Security Policy provides a layer to your [defense-in-depth](https://www.upguard.com/blog/defense-in-depth) cybersecurity practices.

A \[.rt-script]Content-Security-Policy\[.rt-script] header defines directives for server governance on website behaviors through the HTTP header, though you can also supply HTML \[.rt-script]meta\[.rt-script] tags with a string-matching attribute that sets a CSP for the page. The HTTP header is the preferred and recommended method to ensure representation across resources, whereas the HTML element would be limited to the document in which it is set.

With your CSP, you define the approved origins for content that browsers will load on your website, such as JavaScript, CSS stylesheets, images, and more. Without a CSP, malicious actors can inject their preferred content into your website, such as injecting a malicious script in a cross-site scripting attack or manipulating user behavior through a clickjacking attack. XSS attacks and UI redress are two attack vulnerabilities that could be exploited without a Content Security Policy that defines authorized content sources.

When you create your policy, you will supply your preferred directives to define the behavioral policy for your content resources. If you use a content delivery network (CDN), you may want to set up both the Content Security Policy and Cross-Origin Resource Sharing (CORS).

## How to Create a Content Security Policy

By adding the \[.rt-script]Content-Security-Policy\[.rt-script] HTTP header to your website, you configure this policy to protect your website. When you create your policy, you include a set of directives that provide additional specifications for how your site enables origin permissions with content on your website. This origin policy determines how the client-side browser can access resources.

To create the Content Security Policy for your website, you will need to update the configuration file containing your HTTP Response header. Different server setups and hosting platforms require different approaches to your configuration files. For example, you update the \[.rt-script].htaccess\[.rt-script] or \[.rt-script].httpd.conf\[.rt-script] files for Apache web servers, whereas NGINX servers require modification in the server block.

Use the [Mozilla Developer Resources guide to the Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) to identify which CSP directives you may need for your site. Supply your preferred policy directives as a directive and value pair in a semicolon-separated list. The syntax for a Content Security Policy HTTP header is as follows:

\[.rt-script]Content-Security-Policy: \<directive> \<value>; \<directive> \<value>\[.rt-script]

Your policy should always include the \[.rt-script][default-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src)\[.rt-script] directive, which will provide a fallback for any undefined resource types. The \[.rt-script]default-src\[.rt-script] directive is often paired with the \[.rt-script]'self'\[.rt-script] value to define all content origination from only that site's own origin. In that circumstance, the policy would read as follows:

\[.rt-script]Content-Security-Policy: default-src 'self'\[.rt-script]

If you set \[.rt-script]default-src 'none'\[.rt-script], then you need to supply additional directives to allow some resources for specific tasks as no resources will load for instances with the \[.rt-script]none\[.rt-script] keyword. Beyond the \[.rt-script]default-src\[.rt-script] directive, you can determine which directives will suit your organization's needs.

As you prepare your header with allowed sources, be intentional about which sources are specified by your allowlist. Granular permissions will lower your attack surface, whereas broad permissions, such as a wildcard domain pointing to an Amazon S3 bucket, can widen your vulnerable attack surface. If an attacker knows your site is vulnerable and can identify your allowable sources, they could spin up their own wildcard subdomain from the same allowed source (such as an AWS S3 bucket) to load and inject malicious code into your wildcard entity. Tightened permissions for allowed sources can help to prevent this type of bypass attack.

Refer to the examples in the next section for commonly used directives as you define your CSP.

### Sample CSP Headers

This section provides brief examples for some commonly used directives. Your CSP may include these or other directives, and these examples are provided as an educational resource. Be sure that you define a full Content Security Policy that meets your website's security requirements.

To allow content from a trusted domain and its subdomains, append the \[.rt-script]self\[.rt-script] value with the trusted domain and a wildcard identifying subdomains (replacing \[.rt-script]your\_domain\[.rt-script] with your domain):

\[.rt-script]Content-Security-Policy: default-src 'self' your\_domain \*.your\_domain\[.rt-script]

To ensure that all content is loaded using [Transport Layer Security (TLS)](https://www.upguard.com/blog/ssl-certificate), prepend the domain with \[.rt-script]https\://\[.rt-script] (replacing \[.rt-script]example.com\[.rt-script] with your domain):

\[.rt-script]Content-Security-Policy: default-src https\://example.com\[.rt-script]

The \[.rt-script][script-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src)\[.rt-script] directive identifies allowable sources for JavaScript, including inline scripts, event handlers, and information held in \[.rt-script]script\[.rt-script] tags. If you don't provide a source for the \[.rt-script]script-src\[.rt-script] directive, it will fallback to the source allowed by your \[.rt-script]default-src\[.rt-script] directive. With this directive, you can supply a nonce-source or hash-source that dynamically generates a cryptographic token, which would allow an inline script when your policy would otherwise disallow it. The following CSP header would allow scripts from the self-origin and your domain:

\[.rt-script]Content-Security-Policy: script-src 'self' https\://your\_domain\[.rt-script]

Whereas if you generate a file hash, you would include that in both the directive and with an \[.rt-script]integrity\[.rt-script] attribute in your \[.rt-script]script\[.rt-script] tag. The policy would be similar to the following with your unique alphanumeric hash string:

\[.rt-script]Content-Security-Policy: script-src 'sha384-your\_alphanumeric\_hash\_string'\[.rt-script]

You can specify allowed sources for different types of content using other directives, such as the \[.rt-script][img-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src)\[.rt-script] or \[.rt-script][style-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src)\[.rt-script] directives, depending on your web application's needs. If your site servers a large variety of content and you want to protect against content injection attacks, your \[.rt-script]Content-Security-Policy\[.rt-script] header can become lengthy to account for the distinctions made between different content sources.

As you set your policy, you might want to test the deployment in a reporting mode. Appending \[.rt-script]-Report-Only\[.rt-script] to the header will report any policy violations to a provided resource identifier (URI) without enforcing the policy itself. Instead of the \[.rt-script]Content-Security-Policy\[.rt-script] HTTP header, you would use the \[.rt-script]Content-Security-Policy-Report-Only\[.rt-script] header.

To enable reporting on your active policy, specify the \[.rt-script][report-to](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to)\[.rt-script] directive with the URI to collect CSP violation reports in the manner you set, such as in the following header (replacing \[.rt-script]your\_domain\[.rt-script] with your domain):

\[.rt-script]Content-Security-Policy: default-src 'self' your\_domain; report-to http\://reports.your\_domain/collector.cgi\[.rt-script]

You can then review your CSP reports to analyze how your content policy functions and identify any issues resulting from configuration. The \[.rt-script]report-to\[.rt-script] directive will replace the deprecated \[.rt-script][report-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri)\[.rt-script] directive, though you can include both directives for compatibility across browsers that may not yet support \[.rt-script]report-to\[.rt-script].

Other commonly deployed directives include \[.rt-script][base-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/base-uri)\[.rt-script] to govern \[.rt-script]\<base>\[.rt-script] elements, \[.rt-script][child-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/child-src)\[.rt-script] for nested browsing contexts, \[.rt-script][connect-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/connect-src)\[.rt-script] to restrict specific APIs and WebSockets, \[.rt-script][font-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src)\[.rt-script] for permitted fonts, \[.rt-script][form-action](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/form-action)\[.rt-script] for form submissions, \[.rt-script][frame-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src)\[.rt-script] for \[.rt-script]\<frame>\[.rt-script] and \[.rt-script]\<iframe>\[.rt-script] elements, \[.rt-script][media-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/media-src)\[.rt-script] for \[.rt-script]\<audio>\[.rt-script] and \[.rt-script]\<video>\[.rt-script] elements, and \[.rt-script][object-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/object-src)\[.rt-script] for plugins like the \[.rt-script]\<object>\[.rt-script] and \[.rt-script]\<embed>\[.rt-script] elements.

## Common Issues with CSP Configuration

You can perform manual validation review to gauge how your Content Security Policy is set up, or you can use a continuous monitoring tool like [UpGuard Breach Risk](https://www.upguard.com/product/breach-risk) to automate your configuration review.

When Breach Risk examines your website, our scanning techniques can identify common configuration issues that may occur during your CSP setup. Breach Risk identifies the following findings related to CSP configuration:

* **CSP is not implemented**
* **CSS implemented unsafely**
* **CSP contains unsafe-eval**
* **CSP allows insecure active sources**
* **CSP allows insecure passive sources**

You'll receive the CSP is not implemented finding if the Content-Security-Policy header (or an equivalent \<meta> tag) is missing — or if one is present but doesn't declare any directive that actually restricts where content can load from. For example, a policy that only configures violation reporting (report-to/report-uri) with no default-src, script-src, object-src, or similar restriction still counts as no policy at all, since there's nothing for the browser to enforce. To remedy this issue, add a CSP header (or meta tag) that explicitly restricts content sources — at minimum script-src and object-src — to help prevent XSS and injection attacks.

If your CSP is not configured correctly or if you allow certain sources, then your site may remain vulnerable to certain injection attacks. Removing the \[.rt-script][unsafe-inline\[.rt-script\] and \[.rt-script\]unsafe-eval\[.rt-script\] options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#unsafe_keyword_values) from the CSP header to correct the **CSP implemented unsafely** and **CSP contains unsafe-eval** findings. Because \[.rt-script]unsafe-inline\[.rt-script] permits the use of inline resources and \[.rt-script]unsafe-eval\[.rt-script] allows dynamic code, a site with those directives remains vulnerable to XSS and injection attacks as attackers could insert malicious code like executable JavaScript.

Additionally, you should ensure your authorized sources are set correctly to allow only the specified server origins, script endpoints, and controlled resources. Implementing the \[.rt-script][upgrade-insecure-requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests)\[.rt-script] option will force the server to read all HTTP requests over [HTTPS](https://www.upguard.com/blog/what-is-https) and otherwise block any insecure requests that cannot be upgraded.

In addition to the top-level notification, UpGuard identifies which assets have triggered this risk, when the issue was detected, and how the expected values compare to the actual header. When you know which website or IP address triggers these findings, you can then update the specific asset to ensure the correct configuration. After updating your assets, you can wait for UpGuard's daily scan or [rescan the asset for a real-time update](https://help.upguard.com/en/articles/3833967-how-to-rescan-a-domain-in-upguard-breachsight).

Once you know which of your domains or IP addresses need to have the Content Security Policy modified, you can update your CSP configuration settings.

eBook

A Complete Guide to Data Breaches

Free resource

### A Complete Guide to Data Breaches

Learn how to avoid a costly data breach with a comprehensive prevention strategy.

[Download now](/resources/complete-guide-to-data-breaches)

## Related posts

Learn more about the latest issues in cybersecurity.

Risks and Vulnerabilities

#### [25 Security Vulnerabilities That Have Defined the 2020s (Thus Far)](/blog/top-25-security-vulnerabilities-of-the-2020s)

From Log4j to SolarWinds, discover the 25 critical security vulnerabilities that have reshaped cybersecurity thus far in the 2020s.

[](/team/nicholas-sollitto)

[Nicholas Sollitto](#)

May 28, 2026

Risks and Vulnerabilities

#### [ServiceNow Vulnerabilities: CVE-2024-4789 and CVE-2024-5217](/blog/servicenow-vulnerabilities)

Learn about two critical vulnerabilities affecting the ServiceNow platform (CVE-2024-4789 and CVE-2024-5217) and how UpGuard can help.

[](/team/nicholas-sollitto)

[Nicholas Sollitto](#)

January 16, 2025

Risks and Vulnerabilities

#### [PHP2Shell: A Clear Explanation and Response Framework](/blog/php2shell-a-clear-explanation-and-response-framework)

PHP2Shell (CVE-2026-109618 and CVE-2026-109619) lets unauthenticated attackers run code on PHP servers. Learn who’s affected and how to respond.

[](/team/upguard)

[UpGuard Team](#)

October 26, 2026

Risks and Vulnerabilities

#### [Everything Everywhere: Systemic Data Exposure in Supabase Apps](/blog/everything-everywhere-systemic-data-exposure-in-supabase-apps)

Supabase is a favorite of AI coding agents. It's also prone to misconfiguration. We studied more than 16,000 open databases to see what's leaking.

[](/team/greg-pollock)

[Greg Pollock](#)

October 14, 2026

Risks and Vulnerabilities

#### [Oracle Just Shipped 1,449 Security Patches in One Quarter. We Checked How Much of It Is Actually New.](/blog/oracle-just-shipped-1-449-security-patches-in-one-quarter-we-checked-how-much-of-it-is-actually-new)

Oracle's July 2026 update shipped 1,449 security patches — 2.8x its all-time record. We parsed 23 quarters of advisories to find out how much is truly new.

[](/team/greg-pollock)

[Greg Pollock](#)

July 22, 2026

Risks and Vulnerabilities

#### [Data leakage risks with DBHub MCP servers](/blog/data-leakage-risks-with-dbhub-mcp-servers)

UpGuard found exposed DBHub servers leaking live databases to the open internet—an early sign that MCP exposure is becoming a systemic data risk.

[](/team/greg-pollock)

[Greg Pollock](#)

October 13, 2026

[All posts](/blog)

Experience superior visibility and a simpler approach to cyber risk management

[Get a demo](/contact-sales)

[Free trial](/demo)
