Skip to content
intermediatePhase 41 · Frontend Security

Content Security Policy

Implement CSP headers to prevent code injection attacks.

45m
0 problems
Topic Progress0%

CSP Basics

Content Security Policy

What is CSP?

Content Security Policy restricts which resources can be loaded and executed.

Basic Configuration

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

// Multiple directives
app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' https://trusted.com; style-src 'self' 'unsafe-inline'"
  );
  next();
});

Common Directives

Directive Controls
default-src Default for all resource types
script-src JavaScript files
style-src CSS files
img-src Images
font-src Fonts
connect-src AJAX, WebSocket
frame-src Iframes
object-src Plugins
media-src Audio/Video

Source Values

Value Description
'self' Same origin
'none' Block all
'unsafe-inline' Allow inline
'unsafe-eval' Allow eval()
https: HTTPS only
data: data: URIs
blob: blob: URIs
domain.com Specific domain

Example Policies

// Strict policy
"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self';"

// Relaxed policy
"default-src 'self' https:; script-src 'self' https://trusted.com;"

// Inline styles only
"default-src 'self'; style-src 'self' 'unsafe-inline';"

CSP Directives

CSP Directives

Script Sources

// Only same origin
script-src 'self'

// Specific CDN
script-src 'self' https://cdn.jsdelivr.net

// No inline scripts
script-src 'self'

// Allow specific inline
script-src 'self' 'nonce-abc123'

// Allow specific hash
script-src 'self' 'sha256-abc123...'

Style Sources

// Only external styles
style-src 'self'

// Allow inline styles
style-src 'self' 'unsafe-inline'

// Specific CDN
style-src 'self' https://fonts.googleapis.com

Image Sources

// Only same origin
img-src 'self'

// Allow data URIs
img-src 'self' data:

// Allow any HTTPS
img-src 'self' https:

// Specific domains
img-src 'self' https://images.example.com https://cdn.example.com
},
{
  "id": "ch3",
  "title": "Advanced CSP",
  "content": "## Advanced CSP

Nonces and Hashes

// Generate nonce per request
const nonce = crypto.randomBytes(16).toString('base64');

app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    `script-src 'self' 'nonce-${nonce}'; style-src 'self' 'nonce-${nonce}'`
  );
  res.locals.nonce = nonce;
  next();
});

// In template
<script nonce="{nonce}">
  // Inline script with nonce
</script>

// Hash-based
const hash = crypto
  .createHash('sha256')
  .update('console.log("hello")')
  .digest('base64');

script-src 'self' 'sha256-${hash}'

Reporting

// CSP Report-Only header
app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy-Report-Only',
    "default-src 'self'; report-uri /csp-report"
  );
  next();
});

// Report endpoint
app.post('/csp-report', (req, res) => {
  const report = req.body;
  console.log('CSP Violation:', report);
  res.status(204).end();
});

// Report-To header (newer)
app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; report-to csp-endpoint"
  );
  res.setHeader(
    'Report-To',
    JSON.stringify({
      group: 'csp-endpoint',
      endpoints: [{ url: '/csp-report' }],
      max_age: 10886400,
    })
  );
  next();
});

React CSP Implementation

// server.js
import { randomBytes } from 'crypto';

function generateNonce() {
  return randomBytes(16).toString('base64');
}

app.use((req, res, next) => {
  const nonce = generateNonce();
  res.locals.nonce = nonce;

  const csp = [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    `style-src 'self' 'nonce-${nonce}'`,
    "img-src 'self' data: https:",
    "font-src 'self' https://fonts.gstatic.com",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'",
  ].join('; ');

  res.setHeader('Content-Security-Policy', csp);
  next();
});

// React component
function App({ nonce }) {
  return (
    <html>
      <head>
        <script nonce={nonce} src="/bundle.js"></script>
        <style nonce={nonce}>{css}</style>
      </head>
      <body>
        <div id="root"></div>
      </body>
    </html>
  );
}

Common CSP Mistakes

  1. Using 'unsafe-inline' (weakens CSP)
  2. Using 'unsafe-eval' (allows eval())
  3. Overly permissive policies (https: or *)
  4. Not testing in report-only mode first
  5. Missing directives (default-src fallback)
  6. Not handling nonce properly

Testing CSP

// Test CSP headers
describe('CSP', () => {
  it('should set CSP header', async () => {
    const response = await request(app).get('/');
    expect(response.headers['content-security-policy']).toBeDefined();
  });

  it('should not allow unsafe-inline', async () => {
    const response = await request(app).get('/');
    expect(response.headers['content-security-policy'])
      .not.toContain('unsafe-inline');
  });
});

Practice Problems

0/3solved
Build Content Security Policy (CSP) Component

Create a reusable React component implementing Content Security Policy (CSP). Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Content Security Policy (CSP) Testing

Write unit and integration tests for Content Security Policy (CSP) using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Content Security Policy (CSP) Performance

Optimize Content Security Policy (CSP) for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What is CSP?

Question 1 options

2. What does 'unsafe-inline' allow?

Question 2 options

3. What is the primary purpose of Content Security Policy (CSP)?

Question 3 options

4. What is a common mistake when implementing Content Security Policy (CSP)?

Question 4 options

Flashcards

Question

What is CSP?

Answer

Content Security Policy - an HTTP header that restricts resource loading and execution.

Question

What is the default-src directive?

Answer

Fallback for all resource types when specific directive is not set.

Question

Why avoid unsafe-inline?

Answer

It allows inline scripts/styles, making XSS attacks easier.

Question

What is Report-Only mode?

Answer

Reports CSP violations without blocking resources, useful for testing.

Question

What is Content Security Policy (CSP)?

Answer

Content Security Policy (CSP) is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.CSP restricts which resources can be loaded
  • 2.Use nonces instead of unsafe-inline
  • 3.Start with Report-Only for testing
  • 4.Be specific with allowed domains
  • 5.CSP is a critical defense against XSS

Interview Tips

  • Explain CSP directives and source values
  • Discuss nonces vs hashes for inline scripts
  • Know common CSP configuration mistakes

Cheat Sheet

CSP Cheat Sheet

Directives

  • default-src: Fallback for all
  • script-src: JavaScript
  • style-src: CSS
  • img-src: Images
  • connect-src: AJAX/WebSocket

Source Values

  • 'self': Same origin
  • 'none': Block all
  • 'unsafe-inline': Inline scripts (avoid)
  • 'nonce-abc': Allow specific inline
  • https: HTTPS only

Best Practices

  1. Start with Report-Only
  2. Use nonces for inline
  3. Don't use unsafe-inline/eval
  4. Be specific with domains
  5. Set frame-ancestors 'none'

Header Example

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc';