4.1 KiB
📋 Plan: Security Fixes & Enhancements
Date: December 4, 2025
Branch: feature/beta-release
Status: Draft
🧐 UX & Context Analysis
1. Security Toggles Persistence
Problem: Toggles for CrowdSec, WAF, and Rate Limiting provide feedback but revert state on refresh.
Root Cause: The Backend GetStatus handler reads from static config and ignores the settings table overrides for WAF and Rate Limiting.
Fix: Update GetStatus to check the settings table for all security modules, ensuring the "Source of Truth" is the database, not just the startup config.
2. CrowdSec Dashboard "Blank Page"
Problem: /security/crowdsec renders a blank blue page without header/footer.
Analysis: The component is likely crashing due to unhandled null/undefined data access, or there is a routing/layout issue.
Fix:
- Wrap
CrowdSecConfigin an Error Boundary. - Ensure
statusandlistMutation.dataare accessed safely. - Verify
Layoutwrapping inApp.tsx.
3. Rate-Limiting Dashboard
Problem: /security/rate-limiting loads System Settings.
Fix:
- Create
frontend/src/pages/RateLimiting.tsx. - Implement controls for
enabled,requests_per_second,burst, andwindow. - Update
App.tsxrouting.
4. WAF Presets & Usability
Problem: Users need an easy way to add standard rules (OWASP CRS) without copy-pasting. Fix:
- Add a "Presets" dropdown to the WAF Rule Set form.
- Include "OWASP Core Rule Set (CRS)" and "Common Bad Bots" as built-in presets.
- Presets will auto-fill the "Source URL" or "Content" fields.
🤝 Handoff Contract
Backend Changes
GET /api/v1/security/status
Must respect the following settings table keys:
security.cerberus.enabled(bool)security.crowdsec.enabled(bool) -> overrides mode to 'local' if truesecurity.waf.enabled(bool) -> overrides mode to 'block' (or saved mode) if truesecurity.rate_limit.enabled(bool)security.acl.enabled(bool)
Frontend Changes
- New Page:
RateLimiting.tsx - Updated Page:
WafConfig.tsx(Presets) - Updated Page:
CrowdSecConfig.tsx(Crash fix)
🏗️ Phase 1: Backend Implementation (Go)
1. Security Handler (internal/api/handlers/security_handler.go)
- Modify
GetStatusto query thesettingstable for:security.waf.enabledsecurity.rate_limit.enabledsecurity.crowdsec.enabled
- Logic:
- If
security.waf.enabled== "true", setwaf.enabled = true. - If
security.rate_limit.enabled== "true", setrate_limit.enabled = true.
- If
🎨 Phase 2: Frontend Implementation (React)
1. Fix CrowdSec Dashboard (pages/CrowdSecConfig.tsx)
- Add null checks for
status.crowdsec. - Ensure
listMutation.datais handled when undefined. - Verify
Layoutcontext.
2. Create Rate Limiting Page (pages/RateLimiting.tsx)
- UI:
- Toggle: Enable/Disable
- Input: Requests per second (default: 10)
- Input: Burst (default: 5)
- Input: Window (seconds)
- API: Use
updateSettingfor toggle,updateSecurityConfigfor values.
3. WAF Presets (pages/WafConfig.tsx)
- Add
PRESETSconstant:const PRESETS = [ { name: 'OWASP Core Rule Set', url: 'https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.5.tar.gz', description: 'Industry standard protection against Top 10 vulnerabilities.' }, { name: 'Basic SQL Injection Protection', content: 'SecRule REQUEST_URI "@detectSQLi" "id:1001,phase:1,deny,status:403,msg:\'SQLi Detected\'"', description: 'Simple rule to block common SQL injection patterns.' } ] - Add Dropdown to
RuleSetFormto populate fields.
4. Update Routing (App.tsx)
- Point
/security/rate-limitingtoRateLimitingcomponent.
🧪 Phase 3: Verification
- Toggles: Toggle WAF on/off -> Refresh -> Verify state persists.
- CrowdSec: Navigate to
/security/crowdsec-> Verify page loads with Layout. - Rate Limit: Navigate to
/security/rate-limiting-> Verify new UI. - WAF: Create Rule Set -> Select "OWASP CRS" -> Verify URL is filled.