Files
claude c0f4074a5d Give the audit's open findings a home and a trigger (V-674)
Nineteen of the twenty findings were open, and they lived in an untracked
audit.md at the repo root that no next session would have read. The one that
is closed, the unauthenticated mavgpud proxy, went out as V-673.

The report is now a frozen measurement under docs/evals/, dated and never
edited again — including when a finding it names gets fixed. The live state
moved to docs/caveats/, one entry per limit, each carrying its Vikunja id and
the condition that makes it worth fixing. A caveat with no revisit trigger is
a complaint, so every entry has one. Closing a limit deletes its entry rather
than editing the measurement that found it.

Two directory indexes come with it. docs/CLAUDE.md states the tier rule the
repo already followed by convention: living docs corrected in place, evals
frozen by date, caveats deleted when fixed. docs/caveats/CLAUDE.md indexes the
nineteen by claim and severity, because an index of filenames adds nothing a
directory listing does not.

Tasks V-675 through V-693 carry the plans. The doc line and the tracker now
join in both directions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ESv8hqNPseYt1CnotZpqDz
2026-08-11 10:41:54 +04:00

1.3 KiB

Security

Both entries are mavweb's passkey seam. Assertion itself is sound and is not the problem: userVerification is required, and a sign count that does not increase is rejected.

Anyone past the proxy can enroll a passkey [#683]

Costs: registration is gated on nothing, so any client that reaches mavweb can enroll its own key and become him. Step-up is worse than per-client: one process-global assertedAt means every client inherits the same five-minute window after any successful assertion. The voice WebSocket accepts every origin, which makes cross-site use easier. V-317 covers which routes are gated and V-605 covers challenge-map growth. Neither covers this. Revisit when: mavweb is reachable from anything but the tunnel, and before any new credential is enrolled. Workaround: the reverse proxy is the only boundary today. That is the finding.

Passkey credentials are rewritten in place [#684]

Costs: os.WriteFile over the live file. A crash, a full disk or an interrupted write corrupts every enrolled credential at once, and mavweb will not start afterwards. Revisit when: a second credential is enrolled, since the blast radius grows with the count. Sooner if the box loses power unexpectedly. Workaround: back the file up before enrolling.