Production-ready Content Security Policy configuration for secure CAPTCHA integration
This widget is running with the recommended CSP configuration. Try solving the CAPTCHA to see it in action.
Complete integration guide with examples for Nginx, Apache, Node.js, Django, WordPress, and more frameworks.
Read Full Docs →'unsafe-inline' is Acceptable
While 'unsafe-inline' for styles is required, it represents minimal security risk in this context:
✓ Scripts are still restricted to your domain and https://www.captcha.eu
✓ Network requests are limited to https://www.captcha.eu only
✓ Workers use blob: URLs (see below)
✓ Inline styles cannot execute code or leak data
This configuration provides strong XSS protection while allowing the widget to function properly.
worker-src blob: is RequiredFirefox does not support cross-origin Web Workers, even with proper CORS headers. This is per the HTML specification - Web Workers must be same-origin.
Browser behavior:
Chrome: new Worker("https://captcha.eu/worker.js") ✅ Works with CORS
Firefox: new Worker("https://captcha.eu/worker.js") ❌ SecurityError (always)
Our solution (blob pattern):
1. fetch() the worker script (respects CORS headers ✅)
2. Create a Blob from the script content
3. Create blob URL via URL.createObjectURL()
4. new Worker(blobURL) works because blob URLs are same-origin
This is the industry-standard workaround used by Monaco Editor, Ace Editor, and other major projects.
The blob: directive is safe because the script content is still fetched from https://www.captcha.eu with CORS verification.