onionwire/docs/SECURITY_AUDIT.md

40 lines
2.4 KiB
Markdown
Raw Normal View History

# OnionWire security notes
**This is not a public third-party audit.** It is an in-house review of
commit `2b42864` plus a status check against the current tree. Do not cite it
as “audited.”
Protocol: [PROTOCOL.md](PROTOCOL.md). Claims: [THREAT_MODEL.md](THREAT_MODEL.md).
Original pass: rust-dev, no live hidden service / live wallet. Ignored tests
(`rotate_hs`, `tor_hs`, `two_node`) were not run.
## Finding status (vs current tree)
| Id | Original | Now |
|---|---|---|
| F1 receipt `verified` on OR-match | High — txid **or** addr+amount | **Fixed.** `transfers_match` requires txid ∧ amount ∧ address, all non-empty. |
| F2 chat AEAD empty AAD | Medium — row swap | **Fixed.** AAD `owmsg1 \|\| friend_id_le64 \|\| dir \|\| 0x00 \|\| row_id_le64`. |
| F3 invite concat signature | Medium — field shift | **Fixed on encode.** Domain tag `onionwire-invite-v1` + `0x00` separators. Decode still **accepts** legacy concat so old invites work. |
| F4 Monero address shape-only | Medium | **Fixed.** Base58 + Keccak checksum + network prefixes. |
| F5 wallet RPC no auth | Medium | **Fixed.** HTTP Digest required; open RPC refused; 1 MiB read cap; `.onion` RPC URLs refused. |
| F6 `/wipe` skipped payments | Low | **Fixed.** `/wipe` also `DELETE FROM payments` + WAL checkpoint. Still not forensic. |
| F7 HS logs unredacted onion | Low | **Fixed.** stderr uses a redacted label. `dangerously_trust_everyone` remains on Arti storage only. |
| F8 threat model vs F1F3 | Low | **Fixed** in [THREAT_MODEL.md](THREAT_MODEL.md) when the code landed. |
## Still true / not a “finding we forgot”
- Identity secret key and roster (pubkeys + locators) are **plaintext** in sqlite. Chat bodies are not. Seized laptop without FDE yields who you are and who you talk to.
- Arti onion services are experimental. Fail closed; no C-tor fallback.
- No public third-party audit, no `cargo-audit` gate in CI as of the original pass.
- Invite decode still accepts the legacy concat signature (compatibility).
- Rate limit is availability, not traffic-analysis defense.
- One-shot sessions: no channel binding across file chunks beyond “same Noise peer.”
## Verified correct (original pass, still the protocol)
Noise is `Noise_IK_25519_ChaChaPoly_BLAKE2s`, prologue `onionwire-v1`, 96-byte
identity proofs, loc/prf/inv/rcp signed under the session identity, unknown
`[a-z]{3} ` prefixes dropped, frames length-checked before allocate. See
[PROTOCOL.md](PROTOCOL.md).