Content Security Policy (CSP)
What is Content Security Policy?
Content Security Policy (CSP) is a security feature that controls what resources your app can load from external sources. It acts as a whitelist that tells the browser (WebView) which scripts, stylesheets, images, fonts, and APIs are allowed to load.
Why CSP Matters
CSP is your app's first line of defense against:
- Cross-Site Scripting (XSS) attacks
- Code injection from compromised dependencies
- Unauthorized tracking from third-party scripts
- Data theft through malicious external resources
How CSP Works in Your App
Default Configuration
By default, your app is configured with three sets of headers that provide a permissive but secure baseline. These headers are already set for your internal asset server:
Block 1: No Cache
Purpose: Ensure you always get the latest version of your app files.
Why no caching? Unlike a CDN or remote server, your internal asset server is extremely fast (< 1ms) because files are loaded directly from your device. Caching provides zero performance benefit and can cause stale content issues during development and after updates.
Block 2: Security Headers
Purpose: Protect against common web vulnerabilities.
What these do:
X-Content-Type-Options: nosniff- Prevents MIME sniffing attacksX-Frame-Options: SAMEORIGIN- Prevents clickjacking (your app can't be embedded in malicious iframes)X-XSS-Protection: 1; mode=block- Enables browser XSS filterReferrer-Policy: strict-origin-when-cross-origin- Controls what referrer information is sent with requests
Block 3: Permissive Content Security Policy
Purpose: Allow your app to load resources from anywhere while blocking dangerous legacy plugins.
What this allows:
- ✅ Load scripts from any HTTPS source
- ✅ Load stylesheets from any HTTPS source
- ✅ Load images, fonts, media from anywhere
- ✅ Make API calls to any domain (subject to CORS)
- ✅ Use inline scripts and
eval()(common in game engines) - ❌ Blocks Flash, Java plugins, ActiveX (security risk)
Security benefits even with permissive CSP:
- 🛡️ Prevents Flash Player exploits
- 🛡️ Blocks Java applets
- 🛡️ Disables ActiveX controls
- 🛡️ Stops legacy plugin attacks
Customizing CSP Headers
You can override the default headers by adding custom headers in the SaaS dashboard. Your custom headers will replace the corresponding default headers.
Use Case 1: Self-Contained App (Maximum Security)
If your app doesn't load any external resources (no CDNs, no external APIs, no third-party scripts), use the strictest CSP for maximum security:
Custom headers to add:
What this blocks:
- ❌ External scripts (CDN libraries must be bundled locally)
- ❌ External stylesheets (fonts/styles must be local)
- ❌ External images (all images must be in your app)
- ❌ External API calls (only localhost allowed)
What this allows:
- ✅ All resources from your app's files
- ✅ Inline scripts and styles (needed for many games)
- ✅ Data URLs and blobs (for dynamic content)
Use this if: Your game/app is completely self-contained with no external dependencies.
Use Case 2: External CDNs and APIs (Balanced Security)
If your app loads external resources like CDN libraries, Google Fonts, or calls external servers, you need to allow HTTPS sources while maintaining security:
Custom headers to add:
What this allows:
- ✅ Scripts from any HTTPS source (CDN libraries)
- ✅ Stylesheets from any HTTPS source (Google Fonts, etc.)
- ✅ Images from HTTPS sources
- ✅ API calls to HTTPS endpoints
- ✅ WebSocket connections (wss://)
- ✅ Inline scripts (game engines need this)
What this blocks:
- ❌ HTTP resources (only HTTPS allowed for security)
- ❌ Flash, Java, and legacy plugins
Use this if: Your game/app loads libraries from CDNs or makes requests to external servers.
Use Case 3: Specific External Sources Only
If you want to restrict external resources to specific trusted domains:
Custom headers to add:
What this allows:
- ✅ Scripts only from
cdn.jsdelivr.netandunpkg.com - ✅ Styles only from
fonts.googleapis.com - ✅ Fonts only from
fonts.gstatic.com - ✅ API calls only to
api.yourapp.com - ✅ Images from your specific CDN
Use this if: You want tight control over exactly which external sources can be used.
Use Case 4: WebAssembly and High-Performance Features
If your game uses WebAssembly, SharedArrayBuffer, or high-resolution timers (for advanced games), you need cross-origin isolation headers:
Custom headers to add:
Important: These headers are very strict and may break external resource loading. Only use them if your game specifically requires these features.
Use this if: Your game uses WASM with threads, SharedArrayBuffer, or needs high-performance timing APIs.
Understanding CSP Directives
Here's what each CSP directive controls:
Special Keywords
'self'- Same origin (your app's localhost server)'unsafe-inline'- Allow inline scripts/styles (needed for many game engines)'unsafe-eval'- Alloweval()and similar functionsdata:- Allow data URLs (e.g.,data:image/png;base64,...)blob:- Allow blob URLs (dynamic content)https:- Allow any HTTPS source*- Allow everything (use sparingly)
Common CSP Examples
Example 1: Phaser Game with CDN
Your game uses Phaser from a CDN and doesn't call external APIs:
Example 2: Unity WebGL Game
Unity WebGL games need permissive settings for inline scripts and eval:
Example 3: Game with Google Fonts and External API
Your game uses Google Fonts and calls your API:
Troubleshooting CSP Issues
Issue 1: CSP Blocks External Script
Error in console:
Solution: Add the CDN domain to script-src:
Or allow all HTTPS scripts:
Issue 2: Inline Scripts Blocked
Error in console:
Solution: Add 'unsafe-inline' to script-src:
Issue 3: eval() Blocked
Error in console:
Solution: Add 'unsafe-eval' to script-src:
Issue 4: Font Loading Blocked
Error in console:
Solution: Add the font domain to font-src:
Issue 5: API Call Blocked
Error in console:
Solution: Add your API domain to connect-src:
Or allow all HTTPS APIs:
Testing Your CSP Configuration
Step 1: Check Browser Console
Open your mobile app and check the browser console for CSP violations. Any blocked resources will show errors like:
Step 2: Test External Resources
If your app loads external resources, verify they load correctly:
- ✅ External scripts execute
- ✅ External stylesheets apply
- ✅ External fonts render
- ✅ External images display
- ✅ API calls succeed
Step 3: Verify Security
Ensure your CSP isn't too permissive:
- ❌ Flash/Java plugins are blocked (
object-src 'none') - ❌ Your app can't be embedded in iframes (
frame-ancestors 'none') - ✅ Only trusted domains are allowed
Best Practices
Start Permissive, Then Restrict
- Development: Start with the permissive default CSP to ensure everything works
- Testing: Monitor the console for what resources your app actually loads
- Production: Create a specific CSP that allows only necessary sources
Never Allow Everything in Production
Avoid using * in production CSP. Instead:
- ✅ Use
https:to allow all HTTPS sources - ✅ List specific trusted domains
- ❌ Don't use
*(allows HTTP, which is insecure)
Always Block Plugins
Always include object-src 'none' to block Flash, Java, and other dangerous plugins:
Prevent Clickjacking
Always include frame-ancestors 'none' to prevent your app from being embedded in malicious iframes:
Document Your External Dependencies
Keep a list of all external resources your app uses:
- CDN libraries (jsdelivr, unpkg, cdnjs)
- Font providers (Google Fonts, Adobe Fonts)
- API endpoints (your backend servers)
- Analytics (Google Analytics, etc.)
This helps you create an accurate CSP that allows only necessary resources.
Quick Decision Guide
Summary
Default configuration (already set):
- ✅ No caching (fast local access)
- ✅ Security headers (XSS, clickjacking protection)
- ✅ Permissive CSP (allows external resources, blocks plugins)
You only need to customize if:
- You want stricter security (self-contained app)
- You need specific domain whitelisting
- You use WebAssembly/SharedArrayBuffer features
Remember:
- CSP controls what your app can load
- CORS controls what your API can receive
- Configure CSP in the SaaS dashboard
- Configure CORS on your API server
Next Steps
- Need to call external APIs? → CORS Configuration Guide
- Want to understand the architecture? → WebView Architecture Guide