An interactive security laboratory demonstrating Content Security Policy implementation, showing the evolution from vulnerable applications to secure implementations using various CSP techniques.
Developed by Professionally Evil - A cybersecurity consulting firm specializing in penetration testing, security assessments, and security training.
π Repository: https://github.com/ProfessionallyEvil/csp-slap
This project demonstrates 6 different CSP scenarios:
- Vulnerable (No CSP) - Shows how XSS attacks work without protection
- Basic CSP - Basic Content Security Policy implementation
- Hash-based CSP - SHA-256 hash allowlisting for inline scripts
- NGINX Nonce - Legacy-friendly approach using real NGINX sub_filter implementation β¨
- Helmet Nonce - Application-level nonce generation with Helmet middleware
- Malicious Domain - Simulated attacker-controlled domain (not really a scenario, but supports the others)
Choose one of two deployment methods:
This provides the complete CSP demonstration including real NGINX nonce implementation.
npm installnpm run buildnpm startThe backend will start on http://localhost:3001
Option 4a: Using Pre-built Docker Image (Easiest)
# Pull and run the latest pre-built image
docker run -p 80:80 ghcr.io/professionallyevil/csp-slap:latestOption 4b: Build Your Own Docker Image
# Build and run the complete demo with NGINX
docker build -t csp-demo .
docker run -p 80:80 csp-demoAccess the demo at http://localhost/ or http://demo.example.com/ (after adding to hosts file)
Option 4c: Using Your Existing NGINX
For Windows NGINX Integration:
-
Locate your main NGINX configuration file (typically
C:\nginx\conf\nginx.conforC:\Users\{YourUsername}\nginx\nginx-1.26.1\conf\nginx.conf) -
Add the include directive within your existing
http {}block:
http {
# ... your existing configuration ...
# Include CSP demo configuration
include "C:/path/to/your/csp-demos/csp-nginx.conf";
# ... rest of your existing configuration ...
}- Test and reload NGINX:
# Test the configuration
.\nginx.exe -t
# Reload NGINX (if already running)
.\nginx.exe -s reload
# Or restart NGINX
.\nginx.exe -s stop
.\nginx.exeFor Linux/Unix NGINX Integration:
# Add to your main nginx.conf within the http {} block
include /path/to/your/csp-demos/csp-nginx.conf;
# Or include as a separate config file
sudo cp csp-nginx.conf /etc/nginx/sites-available/csp-demo
sudo ln -s /etc/nginx/sites-available/csp-demo /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxThe backend can run standalone for development purposes, but requires NGINX for full functionality:
npm install
npm run build
npm startTo fully demonstrate the different CSP scenarios as separate domains, add these entries to your hosts file:
Edit C:\Windows\System32\drivers\etc\hosts (run as Administrator):
127.0.0.1 demo.example.com
127.0.0.1 vulnerable.example.com
127.0.0.1 basic-csp.example.com
127.0.0.1 hash-csp.example.com
127.0.0.1 nonce-nginx.example.com
127.0.0.1 nonce-helmet.example.com
127.0.0.1 malicious.example.com
Edit /etc/hosts (requires sudo):
sudo nano /etc/hostsAdd these lines:
127.0.0.1 demo.example.com
127.0.0.1 vulnerable.example.com
127.0.0.1 basic-csp.example.com
127.0.0.1 hash-csp.example.com
127.0.0.1 nonce-nginx.example.com
127.0.0.1 nonce-helmet.example.com
127.0.0.1 malicious.example.com
Using localhost (fallback):
- Navigation: http://localhost/ (shows main navigation page)
Using custom domains (after hosts file setup - Recommended):
- π Main Navigation: http://demo.example.com/ β¨ (Start here!)
- Vulnerable: http://vulnerable.example.com/
- Basic CSP: http://basic-csp.example.com/
- Hash CSP: http://hash-csp.example.com/
- NGINX Nonce: http://nonce-nginx.example.com/ β¨ (Real NGINX implementation)
- Helmet Nonce: http://nonce-helmet.example.com/
- Malicious Domain: http://malicious.example.com/
- Navigation: http://localhost:3001/
β οΈ (Navigation links will not work) - Individual Routes: Available but navigation/forms will be broken
Each main demo scenario includes a "π View JavaScript Code" button that opens detailed code explanations in a new tab:
- Vulnerable Code: http://vulnerable.example.com/code
- Basic CSP Code: http://basic-csp.example.com/code
- Hash CSP Code: http://hash-csp.example.com/code
- NGINX Nonce Code: http://nonce-nginx.example.com/code
- Helmet Nonce Code: http://nonce-helmet.example.com/code
- Try the XSS payload:
<img src=x onerror=alert('XSS!')> - Observe that all scripts execute without restriction
- Cross-origin requests succeed
- Try the same XSS payload - it will be injected but scripts won't execute
- Check browser console for CSP violation reports
- External script loading is blocked
- Timer works because the inline script has a matching SHA-256 hash
- Try XSS payload - blocked because no matching hash
- "Test Inline Script" button demonstrates dynamic script blocking
- Scripts with matching nonce execute normally
- Scripts without nonce are blocked
- Each page load generates a new nonce value
- Simulates attacker-controlled endpoints
- Shows what CSP protects against
The CSP demo now includes real NGINX nonce implementation alongside the existing simulated version:
- Backend Server (Port 3001): Express.js application serving content
- NGINX Proxy (Port 80): Handles CSP headers and nonce injection
- Name-based Virtual Hosting: Different CSP policies per domain
- Sub_filter Module: Live nonce replacement in HTML content
- Real Nonce Generation: Uses
$request_idand$msecfor unique nonces - Sub_filter Replacement: Replaces
__CSP_NONCE__placeholders with actual nonces (placeholder can be randomized for additional security) - Domain-specific CSP: Different policies for each virtual domain
- Rate Limiting: Protects against abuse
- Security Headers: Comprehensive security header management
csp-nginx.conf- Configuration for integration with existing NGINX setupsnginx-container.conf- Self-contained configuration for Docker deploymentDockerfile- Complete containerized demo environment
Edit your main NGINX configuration file:
# Add to your main nginx.conf
http {
# ... your existing config ...
# Include CSP demo configuration
include "C:/path/to/your/csp-demos/csp-nginx.conf";
# ... rest of your config ...
}# Add to your main nginx.conf
http {
# ... your existing config ...
# Include CSP demo configuration
include /path/to/your/csp-demos/csp-nginx.conf;
}# Copy configuration to sites-available
sudo cp csp-nginx.conf /etc/nginx/sites-available/csp-demo
# Enable the site
sudo ln -s /etc/nginx/sites-available/csp-demo /etc/nginx/sites-enabled/
# Test and reload
sudo nginx -t && sudo systemctl reload nginxUsing Pre-built Image (Recommended):
# Complete self-contained deployment
docker run -p 80:80 ghcr.io/professionallyevil/csp-slap:latestBuilding from Source:
docker build -t csp-demo .
docker run -p 80:80 csp-demo- Backend: Express.js with EJS templating
- Reverse Proxy: NGINX with sub_filter module
- CSP Implementation: NGINX headers + Helmet middleware
- Hash Calculation: SHA-256 for script allowlisting
- Nonce Generation: NGINX
$request_id+ Crypto-secure (Helmet) - Containerization: Docker with multi-stage builds
- Contains intentional vulnerabilities for educational purposes
- Do not use vulnerable code patterns in production
- All XSS examples are contained within the demo environment
- Open browser Developer Tools (F12)
- Check the Console tab for CSP violation reports
- Some browsers may need CSP reporting enabled
- Ensure you're running as Administrator (Windows) or using sudo (Linux/Mac)
- Clear browser DNS cache: Chrome β Settings β Privacy β Clear browsing data
- Try incognito/private browsing mode
# Find process using port 3000
netstat -tulpn | grep 3000
# Kill the process (replace PID with actual process ID)
kill -9 PIDcsp-demos/
βββ src/
β βββ index.ts # Express server with CSP configurations
βββ views/
β βββ *.ejs # Demo page templates
β βββ *-code.ejs # Code explanation pages
βββ public/
β βββ css/styles.css # Styling
β βββ js/ # External JavaScript files
βββ package.json # Dependencies and scripts
βββ tsconfig.json # TypeScript configuration
This project is designed for CSP education and demonstration. Feel free to extend with additional CSP scenarios or improve existing demonstrations.
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
- β Free to use for educational and non-commercial purposes
- β Free to modify and extend with your own CSP scenarios
- β Free to share with attribution
- β No commercial use without permission
See the LICENSE file for full details.