Skip to content

dpp-vault: Read-scoped API keys can perform full passport-lifecycle writes #20

Description

@LKSNDRTMLKV

Static read-through audit of crates/dpp-vault. API-key storage/auth itself is sound (high-entropy secrets, SHA-256 hash at rest, constant-time comparison, correct revoked/expired handling); status-list and signature verification are genuinely fail-closed. One verified finding — the most severe in the whole 32-crate audit.

1. Scope enforcement exists but is never called on any mutation handler

Location: src/handlers/create.rs:48, update.rs:17, publish.rs:19, suspend.rs:27, archive.rs:18, eol.rs:37, transfer.rs:35,77
Issue: dpp-types/src/api_key.rs:39-43 defines ApiKeyScope::can_write(), specifically documented to gate passport writes (create/update/publish/suspend/archive) to Write/Admin scope — but a repo-wide grep shows can_write is never called anywhere in dpp-engine. None of the seven mutation handlers check auth.scope at all; they only read auth.user_id for the audit-log actor field. router.rs:118-121 wraps /api/v1/* in auth_middleware, but that middleware only authenticates the bearer token and injects AuthContext — it performs no scope-based authorization. Contrast handlers/api_keys.rs:20, registry_identity.rs:21, operator.rs:36, which correctly call auth.scope.is_admin().
Failure scenario: An operator mints a Read-scoped integration key (documented as intended for GET-only listings, e.g. for a low-trust partner or read-only dashboard). That key can nonetheless POST /api/v1/dpp, publish it (Ed25519-signed, registered with the EU registry), suspend/archive/EOL it, and initiate/accept operator transfers — full passport-lifecycle control despite least-privilege being the entire reason scopes were introduced. This is a real, currently-exploitable privilege escalation for any deployment that has issued a non-Admin key. (See also the related, broader scope-enforcement findings in dpp-types and dpp-dal.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecuritySecurity-relevant issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions