Glossary

Content Security Policy

CSP restricts which resources a browser may load and run on a page. It is a defensive layer against XSS, not a substitute for safe output and validation.

Short definition

Rules for the browser, not a fix for server-side bugs.

Content Security Policy (CSP) is a set of instructions that a server sends to a browser, most often in the Content-Security-Policy header. The browser uses them to decide whether a document may load or run a particular script, style, image, font, iframe, or API connection. The policy narrows the space in which injected content can cause harm.

CSP is most commonly used as defence in depth against cross-site scripting. Correct output escaping, safe HTML handling, and input checks remain essential: CSP can limit the consequences of a vulnerability, but does not remove it or sanitise data. It can also restrict other sites from embedding the page or prevent unwanted browser connections.

Use cases

Where the policy defines practical boundaries

CSP is valuable when an application knows its own resources and can continually verify their allowlist.

  • a PHP application with its own JavaScript, CSS, and images on the same domain
  • an administration interface where a compromised inline script could read user data
  • an online store with payment, analytics, or chat integrations from specific domains
  • a frontend whose connect-src allows calls only to known APIs
  • gradually tightening an older application through report-only mode

Practical example

Gradually tightening an administration interface

The administration interface first sends a report-only policy, and the team observes which first-party assets, CDNs, and integration endpoints the page actually uses. Inline onclick handlers are moved to JavaScript, and one small dynamic script receives a nonce generated for the response.

After critical screens have been verified, the same policy is switched to enforcement mode. The nonce value below is only a placeholder: in the application it is generated with cryptographic randomness for every response and inserted into both the header and the allowed element.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{náhodná-hodnota-pro-response}';
  style-src 'self';
  img-src 'self' https://images.example-cdn.test;
  connect-src 'self' https://api.example.test;
  object-src 'none';
  frame-ancestors 'self';
  base-uri 'self'

How it works

From the server response to the browser decision

This flow shows the simple decision the browser makes for every protected resource.

  1. The server sends the header For example, default-src sets the default sources, while specialised directives add scripts, images, or connections.
  2. The document requests a resource HTML, CSS, or JavaScript attempts to load a file, embed an iframe, or call an external API.
  3. The browser checks the rule It uses the specific directive, such as script-src or connect-src, or falls back to default-src.
  4. The resource is allowed or blocked An allowed resource loads; a violation is blocked in enforcement mode or only reported in report-only mode.
  5. The team verifies the impact Reports, the browser console, and functional tests help add legitimate sources without opening an unnecessarily broad exception.

Key concepts

Directives should have a narrow, explainable purpose.

A policy is clearer when every exception corresponds to an actual part of the application or integration.

default-src and resource types

default-src is the default restriction. script-src, style-src, img-src, font-src, and connect-src refine it for specific resource types. self means the same origin, not any secure domain.

Nonce and hash

A nonce is an unpredictable value generated anew for each relevant response, which the browser compares on an allowed script or style. A hash suits known, immutable inline content. Both approaches are more precise than a blanket unsafe-inline.

frame-ancestors and object-src

frame-ancestors controls who may embed the page in a frame; object-src can often be disabled with none. These are different boundaries from API loading or checks on a signed-in user.

Report-only

Content-Security-Policy-Report-Only collects violations but does not block the resource. It is used to verify the design before enforcement, not as the final security posture.

Benefits and limitations

Protection is only as precise as its rules.

Benefits

  • restricting unauthorized scripts, resources, and some XSS paths
  • traceable violations when an integration or template changes
  • gradual rollout through report-only mode
  • frame-ancestors as separate protection against unwanted page embedding

Risks and mistakes

  • unsafe-inline or broad wildcards significantly reducing the value of the policy
  • a static or reused nonce not being a secure nonce
  • allowing an overly trusted third party expanding the attack surface
  • an untested policy breaking payments, administration, or asset loading

Scope

Tighten the policy in small, measurable steps.

A practical process starts by auditing scripts, styles, CDNs, and integrations. Report-only mode reveals legitimate violations; inline handlers can then be converted to event listeners, inline scripts replaced with a nonce or hash, and the rules enforced gradually. The policy should be tested on critical paths, not only the home page.

CSP does not replace secure template design, CSRF protection, HTTPS, or authentication. On a page with many legacy inline scripts, restricting object-src and frame-ancestors may already provide value, while a strict script-src can be introduced gradually. The goal is not the longest possible header, but a verifiable minimum set of sources.

What to consider

The policy belongs in a tested operational contract.

Every exception should have a reason, an owner, and a review when the application or provider changes.

  • begin with a report-only header and review actual violations
  • use a nonce or hash for scripts instead of unsafe-inline
  • set object-src none and consider frame-ancestors carefully
  • restrict connect-src to known APIs and test both signed-in and signed-out paths
  • check the header in automated HTTP tests and after integration changes

Common questions

What CSP addresses in practice

Does CSP replace output escaping?

No. Escaping and safe HTML handling prevent XSS from arising. CSP adds another layer that can restrict malicious content from running or loading.

Does report-only mode already provide protection?

No. The browser only reports violations. It is a safe way to discover the impact on legitimate functionality before enforcing the policy.

Can I simply allow unsafe-inline?

Technically yes, but scripts then lose much of the protection. It is better to replace inline code gradually with a nonce, hash, or external file.

Does CSP ensure that an API call is authorized?

No. connect-src restricts where a browser page may send requests. The API must independently validate the token, session, and permissions on the server.

How I approach security in practice

I assess security layers in the context of the entire application.

When designing and maintaining a website, I address client, API, data, and operational configuration boundaries together.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.