Lightweight service to collect and persist Content Security Policy (CSP) violation reports in Redis for audit and investigation.
- Quick Start
- Configure Your CSP Header
- Configuration
- Data Storage
- Report Formats
- Docker Compose Example
- Rate Limiting
- License
docker run --rm -dp 8080:8080 \
-e REDIS_HOST=your-redis-host \
ghcr.io/meysam81/csp-report-collector
The collector supports both legacy and modern CSP reporting formats:
For older browsers and simpler setups:
Content-Security-Policy: default-src 'self'; report-uri https://csp.example.com
This sends reports with Content-Type: application/csp-report
or application/json
.
For modern browsers with enhanced reporting capabilities:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Report-To: {"group":"csp-endpoint","max_age":86400,"endpoints":[{"url":"https://csp.example.com"}]}
This sends reports with Content-Type: application/reports+json
.
You can also use the newer Reporting-Endpoints
header instead of Report-To
:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="https://csp.example.com"
The Reporting-Endpoints
header provides a simpler syntax compared to Report-To
and is supported by modern browsers.
For maximum compatibility, use all the headers to support old and new browsers:
Content-Security-Policy: default-src 'self'; report-uri https://csp.example.com; report-to csp-endpoint
Report-To: {"group":"csp-endpoint","max_age":86400,"endpoints":[{"url":"https://csp.example.com"}]}
Reporting-Endpoints: csp-endpoint="https://csp.example.com"
All configuration follows the 12-factor app methodology via environment variables:
Variable | Default | Description |
---|---|---|
PORT |
8080 |
HTTP server port |
LOG_LEVEL |
info |
Log verbosity (debug/info/warn/error) |
REDIS_HOST |
localhost |
Redis server hostname (required) |
REDIS_PORT |
6379 |
Redis server port |
REDIS_DB |
0 |
Redis database number |
REDIS_PASSWORD |
- | Redis authentication password |
REDIS_SSL__ENABLED |
false |
Enable TLS connection to Redis |
RATELIMIT_MAX |
20 |
Max requests per IP |
RATELIMIT_REFILL |
2.0 |
Token refill rate per second |
CSP reports are stored in Redis with:
- Key: Unix timestamp of receipt
- Value: Full JSON report
- TTL: Indefinite (configure Redis eviction policy as needed)
The collector accepts both CSP reporting formats:
{
"csp-report": {
"blocked-uri": "inline",
"document-uri": "https://example.com/page",
"effective-directive": "script-src-elem",
"original-policy": "default-src 'self'",
"referrer": "https://example.com/",
"status-code": 200,
"violated-directive": "script-src-elem"
}
}
{
"age": 53531,
"body": {
"blockedURL": "inline",
"disposition": "enforce",
"documentURL": "https://example.com/page",
"effectiveDirective": "script-src-elem",
"originalPolicy": "default-src 'self'",
"statusCode": 200
},
"type": "csp-violation",
"url": "https://example.com/page",
"user_agent": "Mozilla/5.0..."
}
version: "3.8"
services:
csp-collector:
image: ghcr.io/meysam81/csp-report-collector
ports:
- "8080:8080"
environment:
REDIS_HOST: redis
RATELIMIT_MAX: 50
depends_on:
- redis
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
redis-data:
Built-in rate limiting per IP address returns:
X-RateLimit-Total
header with limitX-RateLimit-Remaining
header with remaining requests429 Too Many Requests
when exceeded
Apache License 2.0 - see LICENSE for details.