DevToolBoxGRATIS
Blog

Content Security Policy (CSP) Panduan Lengkap: Dari Dasar ke Produksi

12 menit bacaoleh DevToolBox

Content Security Policy (CSP) is one of the most effective defenses against Cross-Site Scripting (XSS) attacks. By telling the browser exactly which resources are allowed to load, CSP can prevent malicious code injection even when your application has vulnerabilities.

What is CSP and Why Does It Matter?

CSP is an HTTP response header that controls which resources the browser is allowed to load for a given page. Without CSP, a single XSS vulnerability could allow attackers to inject scripts, steal cookies, redirect users, or deface your site.

How CSP Works

When a browser receives a CSP header, it enforces the policy by blocking any resource that violates the rules:

Browser receives HTTP response:
  Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com

Browser allows:
  ✅ <script src="/app.js">              (same origin = 'self')
  ✅ <script src="https://cdn.example.com/lib.js">

Browser blocks:
  ❌ <script src="https://evil.com/steal.js">
  ❌ <script>alert('XSS')</script>       (inline = not allowed)

All CSP Directives

DirectiveControlsExample
default-srcFallback for all resource types'self'
script-srcJavaScript files and inline scripts'self' https://cdn.example.com
style-srcCSS stylesheets and inline styles'self' 'unsafe-inline'
img-srcImages (img, favicon, CSS background)'self' data: https:
font-srcWeb fonts (@font-face)'self' https://fonts.gstatic.com
connect-srcXHR, fetch, WebSocket, EventSource'self' https://api.example.com
media-srcAudio and video elements'self'
frame-srcIframes and embedded frames'self' https://www.youtube.com
object-srcPlugins (Flash, Java applets)'none'
base-uriBase element URLs'self'
form-actionForm submission targets'self'
frame-ancestorsWho can embed this page (anti-clickjacking)'self'
upgrade-insecure-requestsUpgrade HTTP requests to HTTPS(no value needed)

Source Values Explained

SourceMeaning
'self'Same origin (protocol + host + port)
'none'Block all resources of this type
'unsafe-inline'Allow inline scripts/styles (reduces security!)
'unsafe-eval'Allow eval(), Function(), setTimeout(string)
'strict-dynamic'Trust scripts loaded by already-trusted scripts
'nonce-abc123'Allow specific inline script with matching nonce attribute
'sha256-...'Allow inline script matching this hash
https:Allow any HTTPS resource
data:Allow data: URIs (e.g., inline images)
blob:Allow blob: URIs
*.example.comAllow all subdomains of example.com

Step-by-Step Implementation

Step 1: Start with Report-Only Mode

Deploy CSP in report-only mode first to identify violations without breaking your site:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Step 3: Build Your Policy

Create a policy based on your findings. Start strict and relax as needed:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'self';
  base-uri 'self';
  form-action 'self';
  object-src 'none';
  upgrade-insecure-requests

Common CSP Configurations

Strict Policy (Maximum Security)

Content-Security-Policy:
  default-src 'none';
  script-src 'self';
  style-src 'self';
  img-src 'self';
  font-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';
  upgrade-insecure-requests

Moderate (Typical SPA)

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'unsafe-inline' 'unsafe-eval';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: blob: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com wss://ws.example.com;
  frame-ancestors 'self'

With Google Analytics

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;
  img-src 'self' https://www.google-analytics.com https://www.googletagmanager.com;
  connect-src 'self' https://www.google-analytics.com https://analytics.google.com

Implementation Methods

Nginx

add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;

Apache

Header set Content-Security-Policy "default-src 'self'; script-src 'self'"

Express.js

// Using helmet middleware (recommended)
const helmet = require('helmet');
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "https://cdn.example.com"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "data:", "https:"],
  }
}));

// Or manually
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy',
    "default-src 'self'; script-src 'self'");
  next();
});

HTML Meta Tag

<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self'">

Common CSP Mistakes

MistakeImpactFix
Using unsafe-inline for scriptsDefeats XSS protectionUse nonces or hashes instead
Using unsafe-evalAllows eval() and similarRefactor code to avoid eval()
Wildcard (*) in script-srcAllows scripts from any domainWhitelist specific domains
Forgetting about inline stylesBlocks CSS-in-JS librariesAdd unsafe-inline to style-src or use nonces
Not testing in report-only firstBreaks site functionalityAlways start with report-only mode
Missing base-uri directiveAllows base tag injectionAdd base-uri 'self'

FAQ

What attacks does CSP prevent?

CSP primarily prevents Cross-Site Scripting (XSS) attacks by controlling which scripts can execute. It also helps prevent clickjacking (via frame-ancestors), data injection, and mixed content issues.

Does CSP replace input validation?

No. CSP is a defense-in-depth measure. You should still validate and sanitize all user input. CSP acts as a safety net when other defenses fail.

How do I use CSP with inline scripts?

Use nonces (random tokens added to both the CSP header and script tags) or hashes (SHA-256 of the script content). Avoid unsafe-inline as it defeats the purpose of CSP.

Will CSP slow down my website?

No. CSP is enforced by the browser with negligible performance impact. The header itself is tiny. The only overhead is generating nonces if you use them, which is minimal.

𝕏 Twitterin LinkedIn
Apakah ini membantu?

Tetap Update

Dapatkan tips dev mingguan dan tool baru.

Tanpa spam. Berhenti kapan saja.

Coba Alat Terkait

🛡️CSP Header Generator.ht.htaccess GeneratorNXNginx Config Generator🏷️Meta Tag Generator

Artikel Terkait

Docker Compose Cheat Sheet: Services, Volumes, dan Networks

Referensi Docker Compose: definisi service, volume, network, environment variable, dan contoh stack.

Cara Memperbaiki Error CORS: Panduan Lengkap

Perbaiki error CORS langkah demi langkah.