EkuboProtocol / EkuboProtocol/wallet

Critical: same-user processes can extract wallet keys from generic credential stores

Open
#112 1 comment 0 reactions 0 assignees View on GitHub

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:

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.