Security
SonicJS takes security seriously. As a headless CMS that runs on Cloudflare Workers, we maintain a comprehensive security posture designed for edge-native deployments.
Authentication & Authorization
Password Security
- PBKDF2 key derivation with configurable iterations (default: 100,000) β replaced SHA-256 in v2.8.3
- Passwords are never stored in plaintext
- Configurable password requirements (length, complexity)
Role-Based Access Control (RBAC)
SonicJS enforces role-based permissions across all routes:
| Role | Content | Collections | Users | Plugins | Settings |
|---|---|---|---|---|---|
| Admin | Full CRUD | Full CRUD | Full CRUD | Full access | Full access |
| Editor | Full CRUD | Read only | β | β | β |
| Author | Own content | Read only | β | β | β |
| Viewer | Read only | Read only | β | β | β |
- The entire
/adminpanel requires theadminrole by default - Customizable via
adminAccessRolesincreateSonicJSApp()config - User management routes require
adminrole - Content CRUD requires
admin,editor, orauthor - Collection schema changes require
admin - Plugin management requires
admin
Session Management
- JWT-based authentication with configurable secrets
- JWT secret loaded from environment variable (
JWT_SECRET) β never hardcoded in production - Token expiration and refresh policies
- Secure cookie attributes (HttpOnly, Secure, SameSite)
API Security
CSRF Protection
- Signed double-submit cookie pattern on all state-changing endpoints
- Automatic token generation and validation
- Exempt: safe methods (GET, HEAD, OPTIONS), auth routes, public form submissions, event tracking API, Stripe webhooks, and search API
- Requests with
Authorizationheader (Bearer token or API key) bypass CSRF β CSRF only applies to cookie-authenticated sessions
CORS Configuration
- Cross-origin requests restricted to explicitly allowed origins via
CORS_ORIGINSenvironment variable - No wildcard CORS in production
- Preflight request handling
Rate Limiting
- Authentication endpoints (login, register) are rate-limited to prevent brute-force attacks
- Configurable limits per endpoint
- Automatic lockout after repeated failures
Input Validation & Sanitization
- All user input is sanitized before storage (XSS prevention)
- SQL query parameters are parameterized (injection prevention)
- Sort order parameters validated against strict whitelist
- Content preview output HTML-encoded
- Rich text content sanitized (script tags, event handlers, javascript: URLs stripped)
Infrastructure Security
Security Headers
Every response includes:
Content-Security-Policyβ restricts resource loadingX-Content-Type-Options: nosniffβ prevents MIME sniffingX-Frame-Options: DENYβ prevents clickjackingReferrer-Policy: strict-origin-when-cross-originStrict-Transport-Security(HSTS) β enforces HTTPS in production
Startup Verification
On boot, SonicJS checks your security configuration and warns about:
- Missing
JWT_SECRET(falling back to hardcoded default) - Missing
CORS_ORIGINS(rejecting all cross-origin requests) - Missing
ENVIRONMENTsetting (HSTS not applied)
Cloudflare Workers Advantage
- No server to patch β runs on Cloudflare's infrastructure
- Automatic DDoS protection
- Edge-native TLS termination
- Isolated execution per request (V8 isolates)
- No persistent server state to compromise
Security Audit Plugin
SonicJS includes a built-in Security Audit Plugin that provides security event logging, brute-force detection, and a real-time analytics dashboard. When activated, it automatically monitors all authentication routes and records events to your D1 database.
Key Capabilities
- Event logging - Tracks login successes/failures, registrations, logouts, password resets, lockouts, and suspicious activity
- Brute-force detection - Automatically locks out IPs after 10 failed attempts and email accounts after 5 failed attempts within a 15-minute sliding window (all thresholds configurable)
- Suspicious pattern detection - Flags IPs that attempt logins with 5+ different email addresses (credential stuffing indicator)
- Real-time dashboard - Summary cards, hourly trend charts, top offending IPs, and a critical events feed at
/admin/plugins/security-audit - Searchable event log - Filter events by type, severity, email, or IP address with pagination
- Lockout management - View and manually release active lockouts from the dashboard or via API
- Data export - Export events as JSON or CSV for external analysis
- Configurable retention - Set how long events are kept (default: 90 days) with optional auto-purge
How Lockouts Work
When brute-force detection is enabled, the plugin uses Cloudflare KV for fast lockout state. If the CACHE_KV binding is not available, the brute-force detector gracefully degrades β all KV-dependent methods return safe defaults instead of crashing:
- Each failed login increments counters for the IP and email address
- When an IP exceeds the threshold, it is locked and receives
429 Too Many Requestson subsequent login attempts - When an email exceeds its threshold, that account is locked regardless of the source IP
- Lockouts automatically expire after the configured duration (default: 30 minutes) using KV TTL
API Access
All security audit data is available via authenticated admin API endpoints:
| Endpoint | Description |
|---|---|
GET /api/security-audit/events | List and filter security events |
GET /api/security-audit/stats | Dashboard statistics (24h metrics, trends) |
GET /api/security-audit/stats/ips | Top IPs by failed login count |
GET /api/security-audit/stats/trend | Hourly failed login trend |
GET /api/security-audit/lockouts | List active IP and email lockouts |
DELETE /api/security-audit/lockouts/:key | Release a specific lockout |
GET /api/security-audit/export?format=csv | Export events as CSV or JSON |
Security Hardening Timeline
| Version | Date | Changes |
|---|---|---|
| v2.16.1 | Apr 2026 | Admin panel restricted to admin role by default, configurable adminAccessRoles |
| v2.16.0 | Apr 2026 | BruteForceDetector KV resilience, CSRF exempt path expansion, Authorization header bypass for API clients |
| v2.9.0 | Apr 2026 | RBAC enforcement on all admin routes |
| v2.8.3 | Mar 2026 | SQL injection fix, XSS fixes (reflected + stored), PBKDF2 hashing, CSRF protection, rate limiting, CORS restrictions, security headers, JWT secret to env var |
| v2.8.2 | Mar 2026 | Public form XSS sanitization, content API access restrictions |
Configuration Guide
Required Environment Variables
Set these via wrangler secret put for production deployments:
# Required β generate a strong random secret
wrangler secret put JWT_SECRET
# Required β comma-separated allowed origins
wrangler secret put CORS_ORIGINS
# Example: https://mysite.com,https://admin.mysite.com
# Recommended β enables HSTS header
wrangler secret put ENVIRONMENT
# Value: "production"
Optional Configuration
# Rate limiting (defaults shown)
RATE_LIMIT_MAX=10 # Max attempts per window
RATE_LIMIT_WINDOW=900 # Window in seconds (15 min)
Responsible Disclosure
If you discover a security vulnerability in SonicJS, please report it responsibly:
- Email: security@sonicjs.com
- GitHub: Create a private security advisory
Please do not open public GitHub issues for security vulnerabilities.
We aim to:
- Acknowledge reports within 48 hours
- Provide a fix within 7 days for critical issues
- Credit reporters in the release notes (unless anonymity is requested)
Security Audits
SonicJS has not undergone a formal third-party security audit. We welcome contributions from the security community and credit all reporters. See our security advisories for past reports.
Dependencies
We actively monitor and update dependencies:
- Automated Dependabot alerts with rapid triage
- Regular dependency audits via
npm audit - No unnecessary runtime dependencies in the core package