Content Security Policy

Content Security Policy (CSP) is a security standard that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks. When using CSP with PWAs, proper configuration is essential to allow service worker registration while maintaining security.

Why CSP Matters for PWAs

CSP headers control which resources can be loaded and executed. Service workers require JavaScript execution, which CSP may block if not configured correctly.

Common CSP issues with PWAs:

  • Service worker registration blocked

  • Service worker scripts not loading

  • Workbox scripts failing to load

  • Background sync failures

  • Cache API access denied

Basic CSP Configuration

The PWA Bundle supports CSP nonces for service worker registration:

templates/base.html.twig
circle-check

Manual Nonce Generation

If not using Nelmio, generate nonces manually:

Then add the nonce to your CSP header in a middleware or response listener.

CSP Headers for PWAs

Minimal CSP Configuration

Allows service workers with nonce-based script execution:

Complete PWA CSP Configuration

Comprehensive CSP for a full-featured PWA:

Directive explanations:

  • default-src 'self': Default policy for all resources

  • script-src 'self' 'nonce-{NONCE}': Allow scripts from origin + nonce

  • worker-src 'self' blob:: Allow service workers + blob workers

  • connect-src 'self' wss: https:: Allow fetch/XHR + WebSockets

  • img-src 'self' data: blob: https:: Allow images from multiple sources

  • style-src 'self' 'unsafe-inline': Allow inline styles (or use nonce)

  • font-src 'self' data:: Allow fonts from origin + data URIs

  • manifest-src 'self': Allow manifest from origin

  • media-src 'self' blob:: Allow media + blob URLs

Using Workbox CDN

If using Workbox from CDN, add the CDN to your CSP:

Or configure local Workbox to avoid CDN:

Symfony Configuration

Using Nelmio Security Bundle

Custom Event Subscriber

For custom CSP header management:

Common CSP Issues

1. Service Worker Registration Fails

Error: Refused to execute inline script because it violates CSP directive

Solution: Add nonce to service worker registration script:

2. Workbox Not Loading

Error: Refused to load script from 'https://storage.googleapis.com/workbox-cdn/...'

Solution: Add Workbox CDN to script-src or use local Workbox:

3. fetch() Fails in Service Worker

Error: Refused to connect to 'https://api.example.com'

Solution: Add API domains to connect-src:

4. Images Not Caching

Error: Refused to load image from 'blob:...'

Solution: Add blob: to img-src:

5. Background Sync Fails

Error: Refused to create a worker from 'blob:...'

Solution: Add blob: to worker-src:

Testing CSP Configuration

1. Check CSP Headers

2. Browser DevTools

3. CSP Evaluator

Use Google's CSP Evaluator to validate your policy:

  • https://csp-evaluator.withgoogle.com/

4. Report-Only Mode

Test CSP without blocking (reports violations only):

CSP Reporting

Enable CSP Reports

Collect CSP violation reports to identify issues:

Create Report Endpoint

Production vs Development

Development Configuration

More permissive for easier debugging:

Production Configuration

Strict policy for maximum security:

Best Practices

1. Use Nonces, Not unsafe-inline

2. Use Local Resources

Avoid relying on external CDNs when possible:

3. Minimize 'unsafe-*' Directives

Only use when absolutely necessary:

4. Start Strict, Relax if Needed

Begin with restrictive policy and relax gradually:

5. Monitor Violations

Use report-uri to catch violations in production:

Platform-Specific Considerations

iOS/Safari

Safari has strict CSP enforcement. Ensure:

  • manifest-src 'self' is set

  • worker-src 'self' allows service workers

  • No unsafe-eval in production

Android/Chrome

Chrome supports full CSP spec. Take advantage of:

  • 'strict-dynamic' for script loading

  • 'unsafe-hashes' for specific inline scripts

  • Full nonce support

Progressive Enhancement

Provide fallbacks for browsers without service worker support:

Troubleshooting Checklist

When CSP blocks your PWA:

Resources

  • MDN CSP: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

  • CSP Evaluator: https://csp-evaluator.withgoogle.com/

  • CSP Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html

  • Can I Use CSP: https://caniuse.com/contentsecuritypolicy

Last updated

Was this helpful?