4.9 KiB
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
- Browser ↔ reverse proxy.
- Reverse proxy ↔ application.
- API client ↔ application.
- Application ↔ PostgreSQL.
- Application ↔ writable data volumes.
- Application ↔ read-only import source.
- Backup storage.
- 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.