# SnapOtter Security Audit Report **Date:** 2026-05-13 **Version:** 1.16.0 **Commit:** bc0cac4 (baseline) **Auditor:** Claude (Principal Application Security Engineer) **Scope:** Full codebase + production Docker container ## Executive Summary - Total findings: 45 - CRITICAL: 1 | HIGH: 10 | MEDIUM: 17 | LOW: 12 | INFO: 5 - Fixed in this audit: 39 - Deferred: 6 (with justification) - Security tests added: 104 unit + 7 integration = 111 total - SVG attack payload fixtures: 11 ## Baseline Penetration Test Tested against production Docker container. 28 of 30 OWASP attack vectors blocked at baseline. | # | Attack | Baseline | After Hardening | |---|--------|----------|-----------------| | 10.1 | Path traversal (download) | PASS | PASS | | 10.2 | Path traversal (upload filename) | PASS | PASS | | 10.3 | IDOR on user files | PASS | PASS | | 10.4 | Unauthenticated tool access | PASS | PASS | | 10.5 | Privilege escalation via registration | PASS | PASS | | 10.6 | Privilege escalation via self-update | PASS | PASS | | 10.7 | Session token entropy | PASS | PASS | | 10.8 | Password hash strength | PASS | PASS | | 10.9 | SQL injection (login) | PASS | PASS | | 10.10 | SQL injection (search) | PASS | PASS | | 10.11 | Command injection (filename) | PASS | PASS | | 10.12 | Header injection (CRLF) | PASS | PASS | | 10.13 | Brute force login | FAIL | PASS | | 10.14 | Account enumeration | PASS | PASS | | 10.15 | Default credentials | PASS | PASS | | 10.16 | Debug endpoints | PASS | PASS | | 10.17 | Directory listing | PASS | PASS | | 10.19 | Session fixation | PASS | PASS | | 10.20 | Token reuse after logout | PASS | PASS | | 10.21 | API key after revocation | PASS | PASS | | 10.22 | Malicious file upload | PASS | PASS | | 10.23 | Polyglot file | PASS | PASS | | 10.24 | Audit log completeness | PASS | PASS | | 10.25 | No sensitive data in logs | FAIL | PASS | | 10.26 | SSRF cloud metadata | PASS | PASS | | 10.27 | SSRF localhost | PASS | PASS | | 10.28 | SSRF IP encoding bypasses | PASS | PASS | | 10.29 | SVG XSS (script) | PASS | PASS | | 10.30 | SVG XXE | PASS | PASS | | 10.31 | SVG SSRF | PASS | PASS | | 10.32 | SVG event handler | PASS | PASS | ## Findings Detail ### [CRITICAL] C1: drizzle-orm SQL Injection CVE - **File:** package.json - **CWE:** CWE-89 - **Status:** Fixed - **Fix:** Updated drizzle-orm 0.38.4 to 0.45.2 ### [HIGH] H1: Login Rate Limit Default Too High - **File:** apps/api/src/lib/env.ts:42 - **CWE:** CWE-307 - **Status:** Fixed - **Impact:** 500 login attempts/min allowed brute force at 720K/day - **Fix:** Default changed to 30/min ### [HIGH] H2: Global Rate Limit Disabled - **File:** apps/api/src/lib/env.ts:23, apps/api/src/index.ts:143 - **CWE:** CWE-400 - **Status:** Fixed - **Impact:** Default of 0 resulted in 50,000 req/min effective limit - **Fix:** Default changed to 1000/min; index.ts uses `Math.max(env.RATE_LIMIT_PER_MIN, 1)` ### [HIGH] H3: SVG Sanitizer Missing Protections - **File:** apps/api/src/lib/svg-sanitize.ts - **CWE:** CWE-79, CWE-611 - **Status:** Fixed - **Impact:** CDATA bypass, entity-encoded javascript:, animation-based injection - **Fix:** Added CDATA stripping, XML entity decoding, ``/``/`