- 2026-04-18 initial audit verification (all fixed except H8) - 2026-05-01 audit with 8 new findings (B1-B4, I1-I6) - Plan 4: Security Blocker Fixes implementation plan Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.6 KiB
4.6 KiB
Verification: 2026-05-01 Security Audit
Verified by: Claude Opus 4.5
Date: 2026-05-01
Methodology: Code inspection of referenced file paths and line numbers
Summary
| Finding | File Exists | Lines Accurate | Vulnerability Real | Confidence |
|---|---|---|---|---|
| 1 - Backup KDF NFC | ✅ | ✅ | ✅ | 10/10 |
| 2 - Commit injection | ✅ | ✅ | ✅ | 10/10 |
| 3 - WASM private key exposure | ✅ | ✅ | ✅ | 10/10 |
| 4 - Test env vars in prod | ✅ | ✅ | ✅ | 10/10 |
| 5 - AttachmentId 64-bit | ✅ | ⚠️ off-by-1 | ✅ | 9/10 |
| 6 - Field history plaintext | ✅ | ✅ | ✅ | 10/10 |
| 7 - Device keys non-functional | ✅ | ✅ | ✅ | 10/10 |
| 8 - Path traversal restore | ✅ | ✅ | ✅ | 10/10 |
Verdict: All 8 findings are verified as real vulnerabilities in the current codebase.
Finding-by-Finding Verification
Finding 1 — Backup KDF missing NFC normalization
- File:
crates/relicario-core/src/backup.rs - Claimed lines: 303-312
- Verified: ✅
derive_backup_keyat lines 303-312 passespassphrasedirectly toargon.hash_password_into()without NFC normalization. Compare toderive_master_keyincrypto.rs:224-227which explicitly normalizes. - Impact confirmed: Cross-platform restore failure for non-ASCII passphrases.
Finding 2 — Commit message injection via item titles
- File:
crates/relicario-cli/src/main.rs - Claimed lines: 565, 899-901, 1110, 1327
- Verified: ✅
- Line 565:
format!("add: {} ({})", item.title, item.id.as_str()) - Line 1110:
format!("edit: {} ({})", item.title, item.id.as_str()) - Line 1327:
format!("trash: {} ({})", item.title, item.id.as_str())
- Line 565:
- Impact confirmed: Newlines/control chars in titles corrupt git log output.
Finding 3 — WASM generate_device_keypair crosses private key to JS
- File:
crates/relicario-wasm/src/lib.rs - Claimed lines: 215-227
- Verified: ✅ Function returns
{ "private_key_base64": "..." }asJsValue, exposing ed25519 private key to JavaScript heap. - Impact confirmed: Key material accessible to any JS in service worker context.
Finding 4 — Test env vars ship in production binary
- File:
crates/relicario-cli/src/main.rs - Claimed lines: 445-446, 421-423, 1425-1426
- Verified: ✅
- Lines 421-423:
RELICARIO_TEST_ITEM_SECRET - Lines 445-446:
RELICARIO_TEST_PASSPHRASE - Lines 1425-1426:
RELICARIO_TEST_BACKUP_PASSPHRASE
- Lines 421-423:
- Impact confirmed: All checked in production code without
#[cfg(test)]. Passphrase visible in/proc/<pid>/environ.
Finding 5 — AttachmentId truncated to 64 bits
- File:
crates/relicario-core/src/ids.rs - Claimed lines: 52-57
- Actual lines: 51-56 (off by 1)
- Verified: ✅
&digest[..8]= 8 bytes = 64 bits. Birthday collision at ~2³² work. - Impact confirmed: Attacker with attachment upload can cause silent overwrites.
Finding 6 — get_field_history returns plaintext to JS
- File:
crates/relicario-wasm/src/lib.rs - Claimed lines: 232-265
- Verified: ✅ Returns historical
Password/Concealedvalues as plaintext JSON viav.as_str().to_owned(). - Impact confirmed: Password history exposed to JS heap without Zeroizing.
Finding 7 — Device key system is security theater
- File:
crates/relicario-cli/src/main.rs - Claimed lines: 2151-2221
- Verified: ✅
cmd_device()handles Add/List/Revoke but:- No
sign_commitorverify_signaturefunctions exist anywhere devices.jsonis plaintext and unauthenticated- Revocation has no enforcement mechanism
- No
- Impact confirmed: Users falsely believe device revocation provides security.
Finding 8 — Path traversal on backup restore
- File:
crates/relicario-cli/src/main.rs - Claimed lines: 1619-1626
- Verified: ✅
for item in &unpacked.items { fs::write(target.join("items").join(format!("{}.enc", item.id)), ...)?; }item.idandattachment_idused directly in path construction with no validation. - Impact confirmed: Crafted
.relbakwithid = "../../.bashrc"escapes target directory.
Blockers Assessment
The audit's "Path to Certifiable Safety" section is accurate:
| Blocker | Verified | Severity |
|---|---|---|
| B1 - Device key theater | ✅ Real | High |
| B2 - Backup KDF NFC | ✅ Real | Medium |
| B3 - Test env vars | ✅ Real | Medium |
| B4 - Path traversal | ✅ Real | Medium |
All four blockers are confirmed. B1 is the most dangerous as it misleads users about their security posture.