NOTE: References to dev.legal.org.ua below are historical. Only local and prod environments exist now.
Issue: "Content Security Policy blocks the use of 'eval' in JavaScript" Status: ✅ Fixed Date: 2026-01-21
React/Vite applications sometimes require eval() and inline scripts for proper operation. Without a proper Content Security Policy header, browsers may either:
- Apply overly strict default CSP
- Block JavaScript execution from browser extensions
- Show CSP violation warnings
Error Message:
Content Security Policy of your site blocks the use of 'eval' in JavaScript
Added a development-appropriate CSP header to the nginx configuration that allows React/Vite to function while maintaining reasonable security.
File: Lexwebapp/nginx.conf
# Content Security Policy for React/Vite application
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' data: https:; connect-src 'self' https://dev.legal.org.ua wss://dev.legal.org.ua" always;| Directive | Value | Purpose |
|---|---|---|
| default-src | 'self' |
Default policy: only load resources from same origin |
| script-src | 'self' 'unsafe-inline' 'unsafe-eval' |
Allow scripts from same origin, inline scripts, and eval() |
| style-src | 'self' 'unsafe-inline' https://fonts.googleapis.com |
Allow styles from same origin, inline styles, and Google Fonts |
| font-src | 'self' https://fonts.gstatic.com data: |
Allow fonts from same origin, Google Fonts CDN, and data URIs |
| img-src | 'self' data: https: |
Allow images from same origin, data URIs, and HTTPS sources |
| connect-src | 'self' https://dev.legal.org.ua wss://dev.legal.org.ua |
Allow API calls to dev subdomain (HTTP and WebSocket) |
React and Vite applications may use eval() for:
- Hot Module Replacement (HMR) in development
- Dynamic imports and code splitting
- Source map processing for debugging
- Runtime JSX compilation in some configurations
For development environments, allowing unsafe-eval is acceptable and common practice.
Development (Current):
- ✅
unsafe-inlineandunsafe-evalenabled - ✅ Allows debugging and source maps
- ✅ Faster development workflow
Production (Recommended): For production, consider a stricter CSP:
Content-Security-Policy: "default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://legal.org.ua"Vite production builds typically don't require unsafe-eval.
curl -I https://dev.legal.org.ua/ | grep -i content-security-policyExpected Output:
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; ...
- Open https://dev.legal.org.ua/
- Open Browser DevTools (F12)
- Go to Console tab
- Should see no CSP errors
- Application should load and run normally
In DevTools Console, filter for "CSP" to see any violations:
Content Security Policy: <violation details>
1. Browser Extension Conflict
Some browser extensions inject their own CSP. Try:
- Open in Incognito/Private mode (disables most extensions)
- Disable ad blockers or security extensions temporarily
- Check if error persists
2. Cache Issues
Clear browser cache:
# Chrome/Edge
Ctrl+Shift+Delete → Clear browsing data → Cached images and files
# Firefox
Ctrl+Shift+Delete → CacheOr force reload: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)
3. Verify Nginx Configuration
Check the CSP header is actually being sent:
ssh gate "docker exec lexwebapp-dev cat /etc/nginx/conf.d/default.conf | grep -A 1 Content-Security-Policy"4. Check for Multiple CSP Headers
Multiple CSP headers can conflict. Verify only one CSP header exists:
curl -I https://dev.legal.org.ua/ 2>&1 | grep -i content-security-policyShould see exactly one CSP header.
Instead of unsafe-inline, use nonces:
# Generate random nonce per request
set $csp_nonce $request_id;
add_header Content-Security-Policy "script-src 'nonce-$csp_nonce' 'self'";Then inject nonce into HTML:
<script nonce="<%= nonce %>">...</script>Monitor CSP violations:
add_header Content-Security-Policy "...; report-uri /csp-report";Backend endpoint to log violations:
app.post('/csp-report', (req, res) => {
logger.warn('CSP Violation:', req.body);
res.status(204).end();
});Different CSP for dev vs prod:
Development: Permissive (current configuration)
Production: Strict (remove unsafe-eval)
- MDN: Content Security Policy
- CSP Evaluator - Test your CSP
- Vite Security Best Practices
File: Lexwebapp/nginx.conf
Added CSP header with appropriate directives for React/Vite development.
docker build --platform linux/amd64 --no-cache -f Dockerfile.dev -t lexwebapp-lexwebapp:dev .docker save lexwebapp-lexwebapp:dev | gzip > /tmp/lexwebapp-dev-csp.tar.gz
scp /tmp/lexwebapp-dev-csp.tar.gz gate:/tmp/
ssh gate "gunzip -c /tmp/lexwebapp-dev-csp.tar.gz | docker load"
ssh gate "cd <deployment-root> && docker compose -f docker-compose.dev.yml up -d lexwebapp-dev"curl -I https://dev.legal.org.ua/ | grep -i content-security-policy
# ✅ CSP header present and correctStatus: ✅ CSP Configured and Deployed Environment: Development (dev.legal.org.ua) Impact: Allows React/Vite JavaScript execution including eval()