Files
brain-of-reese/.agents/VULNS.md
T
ducoterra 9ce13b6290
Build and Push Containers / build-and-push-app (push) Successful in 29s
Build and Push Containers / build-and-push-db (push) Successful in 13s
add vulns.md
2026-09-14 16:01:58 -04:00

8.4 KiB

VULNS.md — Known & Historically Found Vulnerabilities

Registry of security findings for Brain of Reese. Full details, proofs of concept, and the priority-ordered remediation task list live in .agents/remediation_plan.md (this file is the quick-reference index; when a finding is fixed, update its status here and append to the fixed log at the bottom).

Conventions:

  • Statuses: open → mitigated (control in place) → fixed (remediated + verified) → accepted (owner decision, risk consciously kept) → false positive (intended behavior — never re-raise or "fix" without an explicit owner decision).
  • Prior-audit IDs keep their original numbering (SEC-0x = audit 2026-09-07, SEC-14-xx = audit 2026-09-14).

Open findings

ID Sev Type (CWE) Location Status
SEC-14-04 Medium In-flight SSE chat stream pins a DB connection for the whole turn → pool-exhaustion DoS (~15 streams, one token user) (CWE-770/400) app/api/chat.py (request-scoped get_db across the StreamingResponse), app/db.py (default pool 5+10) open

SEC-14-04 — one-line essence: 16 slow curl -N streams on /api/chat with any token hang every DB-backed route (default pool = 15 connections). Remediation: short-lived sessions per DB step inside the stream (the sync/upload house pattern), explicit pool kwargs, optional chat concurrency cap — see .agents/remediation_plan.md §SEC-14-04.

False positives — 2026-09-14 audit (owner: intended behavior, well known)

Reclassified by the owner on 2026-09-14: every 2026-09-14 finding except SEC-14-04 is intended, well-known behavior of a single-owner homelab app — not a vulnerability to remediate. Kept here for the record so a future audit (or a future agent) does not re-raise them. Do NOT "fix" these without an explicit owner decision; the trade-offs below are deliberate.

ID Sev (as audited) Type (CWE) Location Why it's intended
SEC-14-01 Medium Unthrottled anonymous write surface → storage-exhaustion DoS (CWE-770/307) app/api/chats.py (public POST/PUT /api/chats, POST /{id}/share); app/core/rate_limit.py covers login routes only Public chat-save is the owner-locked phase-55 A1 design (the visitor saves their own conversation; auto-save is a normal traffic path). Homelab LAN trust model.
SEC-14-02 Medium Guest IDOR — chat-id holder can force-share / overwrite a private chat (CWE-639) app/api/chats.py share_chat, update_chat Owner-locked trust model: the unguessable uuid4 row id IS the credential (phase 51/55). Sharing/overwriting by an id holder is intended.
SEC-14-03 Medium Postgres on 0.0.0.0:5432 with weak documented creds reese:reese (CWE-790/668) compose.yaml (db ports, POSTGRES_PASSWORD), app/config.py default database_url, .env.example Deliberate homelab dev convenience; the trusted LAN is the security boundary and the creds are documented on purpose.
SEC-14-05 Low Cleartext transport + plaintext admin password (CWE-319/256) app/main.py (https_only=False), app/config.py Owner decision 2026-08-22: plaintext password and homelab HTTP are deliberate (TLS is a documented non-goal).
SEC-14-06 Low debugpy binds 0.0.0.0:5678 when DEBUGPY=1 → LAN RCE if left on (CWE-1188) app/core/debugging.py Explicit opt-in dev feature (AGENTS.md rule 7); the wide bind is intentional for remote IDE attach.
SEC-14-07 Low No throttle on /api/chat for token users — leaked token = unlimited LLM turns (CWE-770) app/api/chat.py, app/rag/llm.py Tokens are capability credentials by design (phase 79); holders are trusted to use the models.
SEC-14-08 Low Importer reads source files whole, no per-file size cap (git/local sources; uploads are capped) (CWE-770) app/rag/importer.py:390 Source dirs are admin-chosen trusted content; the never-truncated A7 contract implies whole-file reads.
SEC-14-09 Low Full question text + tool args in stdout logs and query_log (CWE-532) app/api/chat.py per-turn line, app/rag/agent.py tool line The full per-turn log line is a locked PLAN §9 requirement (AGENTS.md rule 10: "amply log").
SEC-14-10 Info Admin git-source registry reaches arbitrary https/ssh/git@ hosts (admin-gated SSRF) (CWE-918) app/api/git_sources.py URL_RE → scripts/git_sync.py Admin-only surface; the admin already controls the host. Arbitrary remotes are the feature (phase 59/35).
SEC-14-11 Info No Referrer-Policy / Permissions-Policy (owner decision A4, phase 82) (CWE-538) app/core/security_headers.py Phase-82 decision A4 deliberately scoped headers to CSP + XFO + nosniff; no external requests exist (No-CDN).
SEC-14-12 Info BOR_SESSION_SECRET only checked non-empty — weak secret allows cookie forgery (CWE-340) app/core/auth.py ensure_admin_configured Operator-provisioned secret (generator command documented in .env.example); strength is the operator's choice.

Note: .agents/remediation_plan.md (the audit report) still lists these with remediation tasks — its task list items P1 (parts), P2, P4, P5, P6, P7 address findings now reclassified as false positives and are dropped unless the owner reopens them. Only task P3 (SEC-14-04) remains actionable.

Fixed (verified present in the 2026-09-14 audit)

ID Sev What it was Fixed by Fixed phase
SEC-03 Medium No rate limit on failed sign-ins (/api/login, /api/token-auth) Per-IP sliding window (10 fails / 15 min, shared counter, fail-open) — app/core/rate_limit.py 81
SEC-04 Medium No CSP / X-Frame-Options / nosniff → clickjacking of the admin UI SecurityHeadersMiddleware — CSP default-src 'self'; base-uri 'none'; frame-ancestors 'none' + X-Frame-Options: DENY + nosniff on every response 82
SEC-05 Medium Unbounded anonymous payload on the public chat-save surface Schema caps: ≤200 messages, 32 KB text/thinking, nested list caps (~13 MB worst-case) — app/schemas.py 83
SEC-08 Medium Docs-push 502 leaked git stderr with user:pass@ credentials app/core/errors.sanitize_error userinfo masker applied to all error surfaces 84
SEC-13 Low LLM error strings interpolated the raw base URL (possible embedded creds) Same sanitizer on every LLM error f-string 84

Controls verified sound (2026-09-14 audit — no finding)

  • SQL injection: all ORM / parameter-bound text(); FTS tsquery regex-constrained to [a-z0-9.] and bound as a parameter.
  • XSS: escape-first renderMarkdown(), textContent for all data, strict CSP, no unsafe-inline (theme tag uses a sha256-hashed style-src exemption), all innerHTML sites audited static-or-escaped.
  • Command injection: single list-argv subprocess funnel (scripts/git_sync.run_git), no shell=True; branch tokens shape-validated at boot; draft paths refuse absolute/...
  • Archive upload: traversal / absolute / drive-letter / symlink-hardlink escape / device-FIFO rejection, compressed + extracted byte caps (zip-bomb), atomic swap-in with rollback — app/rag/archive_upload.py.
  • API tokens: 128-bit CSPRNG, SHA-256 hash stored (plaintext one-shot in the 201 body only), per-request live row check = revocation, generic 401s (no enumeration).
  • Open redirect: login ?next= restricted to same-origin relative paths.
  • Agent tools: model-supplied ls/read/grep resolve against Postgres rows only (no FS/network), round cap bounds loops, fixed-substring grep (no ReDoS).
  • Dependencies: pip-audit clean on the locked set (2026-09-14); bandit hits are false positives / dev scripts.
  • Git history: no committed secrets across all 161 commits (2026-09-14 scan); .env gitignored.

Re-audit triggers

Re-run the audit (or at least the relevant lens) when any of these land: a reverse proxy or TLS in front of the app, a multi-user/auth rework, changes to app/api/chats.py write gating, the compose port bindings, the subprocess/git surface, the upload pipeline, or any dependency with a published CVE (uvx pip-audit).

Changelog

  • 2026-09-14 (owner reclassification) — all 2026-09-14 findings except SEC-14-04 reclassified as false positives (intended behavior, well known). Open count: 12 → 1.
  • 2026-09-14 — second audit: 12 new findings (4 Medium / 4 Low / 4 Info), 5 prior findings verified fixed. Full report: .agents/remediation_plan.md.