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

27 lines
1.3 KiB
Markdown

# 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] {#enrollment}
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] {#credentials}
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.