KeeForge Security Audit — August 1, 2026
Public archive Point-in-time review of the audited and remediated source revisions.<br>Source of record: docs/audits/2026-08-01-security-audit.md in the KeeForge repository; this page mirrors it.
This document is a point-in-time archive of a repository-wide security review,<br>its threat model, the findings that survived review, and the remediation completed<br>immediately afterward. It describes the source at the revisions below; later code<br>may differ.
ItemRevisionAudited source64419db4de0991638cc1925fb4ad4123ac24e299Remediation529807b2170c64f6b94f7c9c070e997cc0e43eeeAudit modeWhole repository, static analysis, medium effortRemediation statusSix canonical issues fixed and regression-tested<br>Executive Summary
The original scan reported twelve findings: two high, six medium, and four low.<br>That count reflected repeated reports of the same code paths. After consolidating<br>by root cause, the result is six distinct issues:
one high-impact key-file derivation failure;
one conditional AutoFill domain-boundary issue;
two low-severity crash/denial-of-service conditions; and
two defense-in-depth gaps involving physical access to an already-unlocked<br>device, a scenario explicitly excluded by KeeForge’s SECURITY.md.
The most important defect was in composite-key derivation. A key file recognized<br>as XML but rejected during validation could be silently omitted. During<br>key-file-only database creation this produced the public constant<br>SHA-256(""); with a password present it reduced the selected protection to the<br>password alone. The fix makes key-file processing fail closed at the shared<br>derivation boundary.
The other issues involved an incomplete public-suffix list used to publish<br>AutoFill identities, two Swift runtime traps on unusual KDBX/passkey values, and<br>inconsistent device-owner authentication around entry editing and deferred locks.<br>All six were addressed in 529807b, with focused tests on iOS and macOS and one<br>targeted iOS UI test.
I reviewed the audited revision and fixing commit directly, reconciled the raw<br>findings with the repository’s security policy, and ran the remediation test<br>passes described below. I did not execute the original scan’s proposed exploit<br>scenarios against the vulnerable revision. In particular, Apple platform behavior<br>for a credential identity registered directly against a public suffix was not<br>validated end to end on a physical device.
Scope and Methodology
Repository coverage
The scan divided the repository into twelve components:
KDBX core models and cryptography;
cloud synchronization services;
the AutoFill extension and shared AutoFill services;
security services, including Keychain, device-owner authentication, passkeys,<br>and screen protection;
persistence, bookmarks, key files, database creation, and shared storage;
application-support services such as clipboard, favicons, and feedback;
view models;
SwiftUI views and application lifecycle code;
the experimental macOS app;
the vendored Twofish implementation;
tests; and
build configuration, CI, and developer tooling.
Five categories were intentionally excluded or treated as non-product material:<br>test fixture data, derived/vendor build artifacts, the historical docs archive,<br>agent workflow definitions, and generated Xcode/icon metadata. The living macOS<br>security note was still considered as product context. All seventeen top-level<br>directories were accounted for by either a scanned component or an explicit<br>exclusion.
Review process
The original static scan used this pipeline:
inventory the repository and partition it into security-relevant components;
build one threat model per component before finding discovery;
dispatch 49 independent source reviewers across the component/category matrix,<br>plus a breadth sweep;
normalize 54 candidate findings into 43 candidate sites;
send each candidate through a three-lens verification panel, requiring at least<br>two positive votes to survive; and
render the twelve surviving reports with source locations, preconditions,<br>impact, and proposed fixes.
The panel completed 128 of 129 planned votes. The missing vote belonged to a<br>candidate already rejected by its other two voters and did not affect any reported<br>finding. Every reported finding received a complete panel.
This was a static process. Agent agreement improved review pressure but was not<br>runtime proof. No application, test, exploit, or proof of concept was run during<br>the original scan.
Cleanup and remediation review
The follow-up review treated the scanner output as claims rather than as final<br>issue boundaries. We regrouped findings by vulnerable code path:
F1, F2, F3, F4, and F7 were one key-file derivation defect;
F5 and F12 were one entry-editor visibility/copy defect; and
F9 and F10 were one passkey length trap.
F6, F8, and F11 were already distinct. This reduced twelve reports to six<br>remediation units without dropping any reported behavior.
Each unit was then compared with...