EkuboProtocol / EkuboProtocol/wallet
Critical: same-user processes can extract wallet keys from generic credential stores
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 4
- Forks
- 2
- Avg merge
- 13h 29m
- Merged PRs (30d)
- 33
Description
Severity
Critical impact; high exploit reliability for the threat model's explicit same-user process actor on Windows and common GNOME Linux desktops.
Finding
The wallet stores both the SQLCipher database key and raw secp256k1 private keys through keyring 4.1.6's default platform stores:
- crates/ekubo-wallet-core/src/policy_store.rs uses the predictable service and user pair org.ekubo.wallet.db / default.
- crates/ekubo-wallet-core/src/custody.rs stores each raw account key under org.ekubo.wallet.private-key.instance / wallet instance UUID.
- keyring's Windows backend uses generic CredWriteW and CredReadW credentials and enables CredEnumerateW.
- keyring's Linux backend uses the Secret Service default collection and searchable service / username attributes.
These stores do not provide application isolation from an ordinary process running as the same desktop user:
- Microsoft documents that generic credentials can be read and written by user processes, and CredReadW reads the current token's logon-session credential set: https://learn.microsoft.com/en-us/windows/win32/secauthn/kinds-of-credentials and https://learn.microsoft.com/en-us/windows/win32/api/wincred/nf-wincred-credreadw
- GNOME documents that any application with the same user's privileges can read secrets from any unlocked keyring: https://wiki.gnome.org/Projects%282f%29GnomeKeyring%282f%29SecurityFAQ.html
No debugger, process injection, administrator access, wallet IPC capability, owner-presence approval, or wallet-process control is required. A sibling process can locate these entries and retrieve the byte blobs through the same public platform APIs.
Impact
A same-user process can obtain the database unwrap key and raw account private keys. It can then sign arbitrary transactions and messages outside ekubo-wallet-core, bypassing policy evaluation, owner presence, approval binding, audit history, and every MCP capability boundary. It can also decrypt all SQLCipher state.
On Windows, credential target enumeration reveals the account-key entry names. On GNOME Linux, Secret Service attribute search can find every entry for the private-key service. The predictable database entry is directly addressable on both.
This contradicts docs/threat-model.md, which treats ordinary same-user process access as in scope while trusting platform credential storage to protect account keys.
Required remediation
Do not store extractable private-key bytes or database unwrap keys in application-wide generic credential stores while same-user processes remain in scope.
Redesign custody around an OS-enforced app-isolated boundary: non-exportable key material plus a policy-enforcing signing broker whose caller identity and request authority cannot be forged by another same-user process. Protect the database unwrap key with the same application boundary. The design must preserve unattended policy execution without exposing an arbitrary-signing oracle.
Random entry names, DPAPI wrapping under the same Windows user, or another Secret Service collection do not repair the boundary. If supported operating systems cannot enforce the intended application identity, narrow the threat model explicitly and warn that any same-user process has full wallet authority.
Also:
- migrate or rotate existing stored keys rather than leaving legacy extractable entries behind;
- add platform integration tests using a separate sibling executable that attempts enumeration and retrieval;
- document the exact Windows, Linux, and macOS guarantees independently before calling the credential store a trust boundary.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading docs/threat-model.md, crates/ekubo-wallet-core/src/policy_store.rs, and crates/ekubo-wallet-core/src/custody.rs to understand the current credential-store boundary. Add platform integration tests using a separate sibling executable to attempt enumeration and retrieval. Done means the custody and database keys use an app-isolated, policy-enforcing boundary, legacy entries are migrated or rotated, and Windows, Linux, and macOS guarantees are documented independently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cryptography, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100