Example of a medium-strict Content Security Policy

A "medium-strict" CSP strikes a balance: it's protective against common threats like XSS (cross-site scripting) and clickjacking, but realistic for many modern websites that rely on inline styles, data URIs for images, or limited third-party resources (e.g., analytics scripts or CDNs). It avoids the full strictness of nonce/hash-based policies (which require server-side changes) while blocking dangerous features like inline scripts and plugins.

Here's a solid example header:

Content-Security-Policy: default-src 'self'; 
                          script-src 'self' https://trusted-scripts.example.com; 
                          style-src 'self' 'unsafe-inline'; 
                          img-src 'self' data: https://images.example.com; 
                          font-src 'self'; 
                          object-src 'none'; 
                          base-uri 'self'; 
                          frame-ancestors 'self'; 
                          upgrade-insecure-requests; 
                          report-uri https://your-report-endpoint.example.com/csp-report

This policy is delivered via the HTTP response header (preferred method). Below, I'll break down each directive with explanations.

Directive Breakdown

DirectiveValue in exampleExplanation
default-src'self'fallback policy for any resource type not explicitly defined. Allows loading only from the same origin (same protocol, host, and port), this is a strong baseline to restrict everything by default
script-src'self' https://trusted-scripts.example.comcontrols where JavaScript can be loaded from. 'self' allows scripts from your own domain, adding a trusted external host (e.g., for analytics like Google Analytics) permits that, notably, no 'unsafe-inline' here—this blocks inline <script> tags, preventing most XSS injections of malicious scripts. No 'unsafe-eval' either, blocking risky functions like eval().
style-src'self' 'unsafe-inline'controls CSS sources. 'self' for external stylesheets from your domain. 'unsafe-inline' allows inline <style> tags and style attributes—common in many sites (e.g., for dynamic styling), but less risky than for scripts since CSS XSS is rarer, for stricter, remove 'unsafe-inline' and use nonces/hashes.
img-src'self' data: https://images.example.comallows images from your domain, data: URIs (e.g., base64-embedded images, common for icons), and a trusted CDN, prevents loading images from arbitrary sources (which could be used for tracking or exploits).
font-src'self'restricts custom fonts to your own domain, blocking potential font-based exploits or unauthorized loading.
object-src'none'blocks all plugins (e.g., Flash, Java applets)—obsolete and high-risk technologies. 'none' is strongly recommended for modern sites.
base-uri'self'prevents manipulation of the <base> element, which could redirect relative URLs and enable phishing-like attacks.
frame-ancestors'self'controls who can embed your page in <iframe><frame>, etc. 'self' prevents clickjacking by blocking embedding from other sites. (Obsoletes the older X-Frame-Options header.)
upgrade-insecure-requests(no value needed)automatically upgrades HTTP requests to HTTPS, helping mitigate mixed-content issues without breaking legacy links.
report-urihttps://your-report-endpoint.example.com/csp-reportsends violation reports (e.g., blocked resources) to your endpoint for monitoring. Use this to detect attacks or misconfigurations. (modern alternative: report-to with Reporting-Endpoints header.)

Why this is "medium-strict":

  • protective: blocks inline scripts, plugins, and framing; enforces same-origin defaults; upgrades to HTTPS.
  • realistic: allows 'unsafe-inline' for styles and data: for images, common in real-world apps without requiring major refactoring.
  • for full strictness, switch to nonce-based (e.g., script-src 'nonce-randomValue' 'strict-dynamic'; style-src 'nonce-randomValue';)—ideal but needs dynamic nonce generation per page.

Always start with Content-Security-Policy-Report-Only first to test without blocking, monitor reports, then enforce. Tools like Google CSP Evaluator can help validate your policy.