Commit 05fa81

2026-03-16 04:56:51 Claude (MCP): [mcp] Add OWASP 2025 audit findings
/dev/null .. Security/OWASP_2025_Audit.md
@@ 0,0 1,78 @@
+ ---
+ category: reference
+ tags: [security, owasp, audit]
+ last_updated: 2026-03-16
+ confidence: high
+ ---
+
+ # OWASP 2025 Audit
+
+ ## Executive Summary
+
+ | # | Category | Score |
+ |---|----------|-------|
+ | A01 | Broken Access Control | 6/10 |
+ | A02 | Cryptographic Failures | 6/10 |
+ | A03 | Injection | 7/10 |
+ | A04 | Insecure Design | 7/10 |
+ | A05 | Security Misconfiguration | 6/10 |
+ | A06 | Vulnerable and Outdated Components | 5/10 |
+ | A07 | Identification and Authentication Failures | 6/10 |
+ | A08 | Software and Data Integrity Failures | 7/10 |
+ | A09 | Security Logging and Monitoring Failures | 5/10 |
+ | A10 | Server-Side Request Forgery / Other | 6/10 |
+
+ ---
+
+ ## Critical/High Findings (Fixed)
+
+ These four issues are being addressed in the current sprint on `feat/consent-csrf` and `feat/wiki-slug-consent-param`.
+
+ 1. **Open redirect via `return_to`** — Unvalidated redirect target after OAuth login could send users to attacker-controlled URLs. Fixed on `feat/consent-csrf`.
+ 2. **Default Flask secret key** — Flask session signing key was not set, falling back to a hardcoded default. Fixed on `feat/consent-csrf`.
+ 3. **Non-tenant passthrough grants full ADMIN** — A missing tenant check in the passthrough auth path allowed any authenticated user to receive ADMIN-level access. Fixed on `feat/consent-csrf`.
+ 4. **Consent key derived from PEM header only** — The consent nonce was derived from a non-secret prefix of the PEM key, making it predictable. Fixed on `feat/consent-csrf` + `feat/wiki-slug-consent-param`.
+
+ ---
+
+ ## Remaining Findings (Prioritized)
+
+ ### High Priority (address soon)
+
+ | Finding | OWASP Category |
+ |---------|---------------|
+ | Unpinned git deps in Ansible deploy | A03, A08 |
+ | No version pinning / lock files | A03 |
+ | No security response headers | A02 |
+ | No rate limiting | A06, A07 |
+ | Bcrypt linear scan DoS | A06, A07 |
+ | No security logging | A09 |
+
+ ### Medium Priority
+
+ | Finding | OWASP Category |
+ |---------|---------------|
+ | Bearer token not wiki-scoped IDOR | A01 |
+ | `assert` used as security guards | A10 |
+ | `did:plc` resolution has no timeout | A07, A10 |
+ | Unbounded `find_orphaned_notes` fan-out | A10 |
+ | ATProto tokens stored plaintext | A07, A08 |
+ | Wiki count TOCTOU race | A06 |
+ | Quota cron wrong path | A06 |
+ | `debug=True` in `__main__` blocks | A02 |
+
+ ### Low Priority
+
+ | Finding | OWASP Category |
+ |---------|---------------|
+ | Open DCR on MCP server | A06, A07 |
+ | DELETE excluded from quota enforcement | A01, A06 |
+ | `application = None` on startup failure | A10 |
+ | Silent `except: pass` in rollback paths | A10 |
+ | No upper bound on git-upload-pack body size | A10 |
+
+ ---
+
+ ## Methodology
+
+ 10 parallel Sonnet agents were run, one per OWASP Top 10 category, auditing the `robot.wtf` and `otterwiki-mcp` repos. Findings were cross-validated — the same issues were independently flagged by multiple auditors, increasing confidence in the critical findings.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9