# Threat model ## Assets - User credentials and sessions. - Wiki and project content. - Revisions and audit attribution. - Attachments. - API service tokens. - LeafWiki source snapshot. - Database and backups. - Data-protection and backup keys. - Host filesystem and Docker socket. - Availability and integrity of the Unraid deployment. ## Trust boundaries 1. Browser ↔ reverse proxy. 2. Reverse proxy ↔ application. 3. API client ↔ application. 4. Application ↔ PostgreSQL. 5. Application ↔ writable data volumes. 6. Application ↔ read-only import source. 7. Backup storage. 8. Container ↔ Unraid host. ## Threat register | ID | Threat | Primary controls | Required verification | |---|---|---|---| | T01 | First-run owner registration race | atomic single-use setup; CSRF; setup rate limit | concurrent setup integration test | | T02 | Password brute force/account enumeration | adaptive hashing; generic errors; lockout; rate limit | auth abuse tests | | T03 | Session theft/fixation | secure cookie; rotation; bounded life; security stamp | session lifecycle tests | | T04 | CSRF mutation | same-origin; anti-forgery; SameSite | CSRF integration tests | | T05 | Horizontal/vertical authorization bypass | application-layer policies; scoped queries | role/object substitution matrix | | T06 | Search metadata leakage | permission filter before ranking/facets/snippets | rare-term private-page tests | | T07 | Stored XSS in Markdown/Mermaid | no raw HTML; sanitizer; strict Mermaid; CSP | XSS corpus/browser test | | T08 | Malicious attachment execution | signature validation; download-only policy; nosniff; authorization | upload/serving corpus | | T09 | Path traversal/symlink escape | hash paths; normalized bounded import root; no unsafe following | traversal fixture tests | | T10 | LeafWiki source mutation | RO mount; immutable SQLite; before/after fingerprint | source hash proof | | T11 | Import overwrite/data loss | preflight; explicit conflicts; provenance; rollback | conflict/idempotency/rollback tests | | T12 | API token theft/database recovery | random 256-bit secret; verifier only; revoke/expiry; no logs | token lifecycle/log tests | | T13 | Concurrency overwrite | ETag/If-Match; drafts; conflict UI | concurrent edit E2E | | T14 | Backup theft/tamper | storage controls; optional authenticated encryption; manifest hashes | corrupt/encrypted backup tests | | T15 | Restore of incompatible/corrupt data | compatibility checks; clean-target restore; integrity checks | restore matrix | | T16 | Secret leakage through logs/support bundle | structured redaction; safe exports | secret canary scan | | T17 | Container-to-host escalation | non-root; read-only root; dropped caps; no Docker socket | image/runtime inspection | | T18 | SSRF through project links/import metadata | no server fetch of user URLs; bounded local roots | SSRF negative tests | | T19 | Denial of service via parser/search/upload | size/complexity bounds; timeouts; rate limits; streaming | resource-limit tests | | T20 | Audit/history tampering through normal app | append-only paths; restricted DB behavior; immutable revisions | mutation/permission tests | | T21 | Service account scope escalation | explicit scopes plus content auth; no admin bypass | API scope matrix | | T22 | Outbox/job duplicate side effects | idempotency; leases; attempt state | restart/retry tests | | T23 | Unsafe database migration | backup; compatibility gates; rehearsal | upgrade/rollback tests | | T24 | Sensitive content in external image requests | external image hotlink disabled by default | renderer/network tests | ## Abuse cases ### Malicious reader guesses page IDs Response must not distinguish inaccessible from nonexistent where doing so leaks existence. Search, attachments, revisions and context use the same resource policy. ### Malicious editor uploads HTML disguised as PNG The server streams, checks signature and applies detected-type policy. It does not render the file inline. Filename and declared MIME are not trusted. ### Imported Markdown contains scripts and unsafe URLs Raw source is preserved for provenance, but normal rendering uses the safe Markdown profile. Import validation includes renderer security tests. ### Stolen service token Administrator can identify token prefix/last use and revoke it. Token cannot log into the browser, exceed scopes or recover the owner password. Mutations remain attributable. ### Compromised app container The container runs non-root, lacks Docker socket and host-wide mounts, and has a read-only root filesystem. Database/files remain at risk within granted access; backups and host security are still required. Do not claim container isolation eliminates this risk. ## Review cadence - Update when trust boundaries, auth, uploads, imports, backup or deployment change. - Perform focused review per milestone. - Perform independent full review in M8. - Record accepted residual risk through ADR or release notes.