- Split config_service.py into config_service.py and jail_config_service.py - Update Docs/Tasks.md, Security.md, TROUBLESHOOTING.md
5.8 KiB
Security — Guidelines and Implementation
Security considerations and implementation details for BanGUI.
HTTP Security Headers
BanGUI implements defense-in-depth against client-side attacks by sending security-related HTTP response headers on all responses.
Headers Implemented
| Header | Value | Purpose |
|---|---|---|
Content-Security-Policy |
default-src 'self' |
Prevents XSS attacks by restricting script, style, font, image, and other resource origins to self only. Browsers refuse to load resources from other origins. |
X-Frame-Options |
DENY |
Prevents clickjacking attacks by forbidding the page from being embedded in <iframe> tags on any origin. |
X-Content-Type-Options |
nosniff |
Prevents MIME-type sniffing attacks by forcing browsers to respect the declared Content-Type. Blocks execution of misidentified scripts. |
X-XSS-Protection |
1; mode=block |
Enables browser XSS filters (legacy header for older browsers). Modern browsers prioritize CSP. |
Implementation
Backend: The SecurityHeadersMiddleware in backend/app/main.py adds these headers to every HTTP response, including error responses and non-API routes.
response.headers["Content-Security-Policy"] = "default-src 'self'"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-XSS-Protection"] = "1; mode=block"
Frontend: The <meta http-equiv="Content-Security-Policy" content="default-src 'self'" /> tag in frontend/index.html provides an additional defense layer in case the backend headers are ever stripped (e.g., by a proxy).
CSP Policy Details
The current policy default-src 'self' means:
- Allowed: Inline scripts, stylesheets, fonts, images, and other resources from the same origin (
self) - Blocked: Resources from external domains, inline event handlers,
eval(), andsetTimeout(string)
Why no 'unsafe-inline'?
'unsafe-inline'defeats CSP's primary purpose (XSS prevention) by allowing arbitrarily-embedded scripts- All scripts and styles must be in separate files (never inline), which is best practice anyway
- The frontend build system (Vite) automatically handles asset bundling and file separation
If external CDN resources are needed:
- Explicitly add the CDN origin to the CSP policy, e.g.:
default-src 'self' https://cdn.example.com - Document the CDN addition with a justification comment
- Ensure the CDN certificate chain is valid and trusted
- Consider using Subresource Integrity (SRI) to verify resource authenticity
Verification
To verify headers are being sent correctly:
-
Chrome DevTools:
- Open DevTools (F12)
- Go to Network tab
- Reload the page
- Click on any request and open the Response Headers section
- Look for
Content-Security-Policy,X-Frame-Options,X-Content-Type-Options,X-XSS-Protection
-
Command line (curl):
curl -I http://localhost:8000/ curl -I http://localhost:5173/ -
Online tools:
Future Improvements
- Stricter CSP: If functionality allows, tighten to
default-src 'none'and explicitly allow individual resources - SRI (Subresource Integrity): Add integrity attributes to external script/style tags to prevent tampering
- Preload headers: Use
Link: <...>; rel=preloadto optimize critical resource delivery - HSTS: Consider adding
Strict-Transport-Securityfor production deployments to force HTTPS
Session Security
See backend/app/middleware/csrf.py and backend/app/middleware/rate_limit.py for CSRF protection and rate limiting.
Password Security
- Passwords are hashed with SHA256 on the frontend before transmission
- The backend never stores plain-text passwords
- See
backend/app/services/auth.pyfor authentication implementation
Database Security
- The SQLite database contains no sensitive data (no passwords, API keys, or tokens stored)
- Database queries use parameterized statements to prevent SQL injection
- See
backend/app/repositories/for data access patterns
Regex (ReDoS) Protection
BanGUI validates all user-supplied regex patterns before they are compiled or stored.
How It Works
- Static analysis via regexploit detects catastrophic backtracking patterns before compilation
- Timeout enforcement stops compilation if it exceeds 2 seconds (prevents hanging on pathological patterns)
- Length limit (1000 characters) prevents memory exhaustion via bloated patterns
Protected Endpoints
All endpoints that accept regex patterns validate them:
- Filter configuration (
prefregex,failregex,ignorregex) - Action configuration (any regex used in actions)
- Direct config editing
ReDoS Pattern Examples
Patterns with nested quantifiers on overlapping text are blocked:
| Pattern | Why Blocked |
|---|---|
(a+)+b |
Plus inside plus — exponential backtracking |
([a-z]+)*d |
Quantifier inside quantifier |
(x+)+y |
Nested quantifiers |
a[bcd]*e[bcd]*e |
Multiple unbounded quantifiers |
Legitimate Complex Patterns
Not all complex patterns are blocked. Email and IP validation patterns typically pass:
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" # OK
r"^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" # OK
If Your Pattern Is Rejected
- Rewrite to avoid nested quantifiers on the same text
- Use atomic groups or possessive quantifiers:
(?>a+)+binstead of(a+)+b - Test locally with Python's
remodule before deploying - If you believe the pattern is safe, check with regexploit directly