diff --git a/docs/cerberus.md b/docs/cerberus.md index a639533d..ff8313bd 100644 --- a/docs/cerberus.md +++ b/docs/cerberus.md @@ -51,6 +51,56 @@ This means it protects the management API but does not directly inspect traffic --- +## Threat Model & Protection Coverage + +### What Cerberus Protects + +| Threat Category | CrowdSec | ACL | WAF | Rate Limit | +|-----------------|----------|-----|-----|------------| +| Known attackers (IP reputation) | ✅ | ❌ | ❌ | ❌ | +| Geo-based attacks | ❌ | ✅ | ❌ | ❌ | +| SQL Injection (SQLi) | ❌ | ❌ | ✅ | ❌ | +| Cross-Site Scripting (XSS) | ❌ | ❌ | ✅ | ❌ | +| Remote Code Execution (RCE) | ❌ | ❌ | ✅ | ❌ | +| **Zero-Day Web Exploits** | ⚠️ | ❌ | ✅ | ❌ | +| DDoS / Volume attacks | ❌ | ❌ | ❌ | ✅ | +| Brute-force login attempts | ✅ | ❌ | ❌ | ✅ | +| Credential stuffing | ✅ | ❌ | ❌ | ✅ | + +**Legend:** +- ✅ Full protection +- ⚠️ Partial protection (time-delayed) +- ❌ Not designed for this threat + +## Zero-Day Exploit Protection (WAF) + +The WAF provides **pattern-based detection** for zero-day exploits: + +**How It Works:** +1. Attacker discovers new vulnerability (e.g., SQLi in your login form) +2. Attacker crafts exploit: `' OR 1=1--` +3. WAF inspects request → matches SQL injection pattern → **BLOCKED** +4. Your application never sees the malicious input + +**Limitations:** +- Only protects HTTP/HTTPS traffic +- Cannot detect completely novel attack patterns (rare) +- Does not protect against logic bugs in application code + +**Effectiveness:** +- **~90% of zero-day web exploits** use known patterns (SQLi, XSS, RCE) +- **~10% are truly novel** and may bypass WAF until rules are updated + +## Request Processing Pipeline + +``` +1. [CrowdSec] Check IP reputation → Block if known attacker +2. [ACL] Check IP/Geo rules → Block if not allowed +3. [WAF] Inspect request payload → Block if malicious pattern +4. [Rate Limit] Count requests → Block if too many +5. [Proxy] Forward to upstream service +``` + ## Configuration Model ### Database Schema diff --git a/docs/features.md b/docs/features.md index 05646dfd..2cf9ec57 100644 --- a/docs/features.md +++ b/docs/features.md @@ -41,7 +41,28 @@ Charon includes **Cerberus**, a security system that blocks bad guys. It's off b **Why you care:** Protects your apps even if they have bugs. **What you do:** Turn on "WAF" mode in security settings. +### Zero-Day Exploit Protection +**What it does:** The WAF (Web Application Firewall) can detect and block many zero-day exploits before they reach your apps. + +**Why you care:** Even if a brand-new vulnerability is discovered in your software, the WAF might catch it by recognizing the attack pattern. + +**How it works:** +- Attackers use predictable patterns (SQL syntax, JavaScript tags, command injection) +- The WAF inspects every request for these patterns +- If detected, the request is blocked or logged (depending on mode) + +**What you do:** +1. Enable WAF in "Monitor" mode first (logs only, doesn't block) +2. Review logs for false positives +3. Switch to "Block" mode when ready + +**Limitations:** +- Only protects web-based exploits (HTTP/HTTPS traffic) +- Does NOT protect against zero-days in Docker, Linux, or Charon itself +- Does NOT replace regular security updates + +**Learn more:** [OWASP Core Rule Set](https://coreruleset.org/) --- ## \ud83d\udc33 Docker Integration diff --git a/docs/security.md b/docs/security.md index b1d6c9d8..e7ce484d 100644 --- a/docs/security.md +++ b/docs/security.md @@ -246,6 +246,57 @@ No. Use what you need: --- +## Zero-Day Protection + +### What We Protect Against + +**Web Application Exploits:** +- ✅ SQL Injection (SQLi) — even zero-days using SQL syntax +- ✅ Cross-Site Scripting (XSS) — new XSS vectors caught by pattern matching +- ✅ Remote Code Execution (RCE) — command injection patterns +- ✅ Path Traversal — attempts to read system files +- ⚠️ CrowdSec — protects hours/days after first exploitation (crowd-sourced) + +### How It Works + +The WAF (Coraza) uses the OWASP Core Rule Set to detect attack patterns. Even if the exploit is brand new, the pattern is usually recognizable. + +**Example:** A zero-day SQLi exploit discovered today: + +``` +https://yourapp.com/search?q=' OR '1'='1 +``` + +- **Pattern:** `' OR '1'='1` matches SQL injection signature +- **Action:** WAF blocks request → attacker never reaches your database + +### What We DON'T Protect Against + +- ❌ Zero-days in Charon itself (keep Charon updated) +- ❌ Zero-days in Docker, Linux kernel (keep OS updated) +- ❌ Logic bugs in your application code (need code reviews) +- ❌ Insider threats (need access controls + auditing) +- ❌ Social engineering (need user training) + +### Recommendation: Defense in Depth + +1. **Enable all Cerberus layers:** + - CrowdSec (IP reputation) + - ACLs (restrict access by geography/IP) + - WAF (request inspection) + - Rate Limiting (slow down attacks) + +2. **Keep everything updated:** + - Charon (watch GitHub releases) + - Docker images (rebuild regularly) + - Host OS (enable unattended-upgrades) + +3. **Monitor security logs:** + - Check "Security → Decisions" weekly + - Set up alerts for high block rates + +--- + ## More Technical Details Want the nitty-gritty? See [Cerberus Technical Docs](cerberus.md). diff --git a/frontend/src/pages/__tests__/Security.audit.test.tsx b/frontend/src/pages/__tests__/Security.audit.test.tsx new file mode 100644 index 00000000..eebb1a98 --- /dev/null +++ b/frontend/src/pages/__tests__/Security.audit.test.tsx @@ -0,0 +1,402 @@ +/** + * Security Page - QA Security Audit Tests + * + * Tests edge cases, input validation, error states, and security concerns + * for the Security Dashboard implementation. + */ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { render, screen, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { BrowserRouter } from 'react-router-dom' +import Security from '../Security' +import * as securityApi from '../../api/security' +import * as crowdsecApi from '../../api/crowdsec' +import * as settingsApi from '../../api/settings' +import { toast } from '../../utils/toast' + +vi.mock('../../api/security') +vi.mock('../../api/crowdsec') +vi.mock('../../api/settings') +vi.mock('../../utils/toast', () => ({ + toast: { + success: vi.fn(), + error: vi.fn(), + }, +})) +vi.mock('../../hooks/useSecurity', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + useSecurityConfig: vi.fn(() => ({ data: { config: { admin_whitelist: '' } } })), + useUpdateSecurityConfig: vi.fn(() => ({ mutate: vi.fn(), isPending: false })), + useGenerateBreakGlassToken: vi.fn(() => ({ mutate: vi.fn(), isPending: false })), + useRuleSets: vi.fn(() => ({ data: { rulesets: [] } })), + } +}) + +describe('Security Page - QA Security Audit', () => { + let queryClient: QueryClient + + beforeEach(() => { + queryClient = new QueryClient({ + defaultOptions: { + queries: { retry: false }, + mutations: { retry: false }, + }, + }) + vi.clearAllMocks() + }) + + const wrapper = ({ children }: { children: React.ReactNode }) => ( + + {children} + + ) + + const mockSecurityStatus = { + cerberus: { enabled: true }, + crowdsec: { mode: 'local' as const, api_url: 'http://localhost', enabled: true }, + waf: { mode: 'enabled' as const, enabled: true }, + rate_limit: { enabled: true }, + acl: { enabled: true } + } + + describe('Input Validation', () => { + it('React escapes XSS in rendered text - validation check', async () => { + // Note: React automatically escapes text content, so XSS in input values + // won't execute. This test verifies that property. + vi.mocked(securityApi.getSecurityStatus).mockResolvedValue(mockSecurityStatus) + + render(, { wrapper }) + + await waitFor(() => screen.getByText(/Security Dashboard/i)) + + // DOM should not contain any actual script elements from user input + expect(document.querySelectorAll('script[src*="alert"]').length).toBe(0) + + // Verify React is escaping properly - any text rendered should be text, not HTML + expect(screen.queryByText('