Safeguard
Cloud Security•

Vault 2.1.2: Four October Bulletins, From ACL Deny Bypass to ACME

HashiCorp's 7 October Vault bulletins fix a case-sensitivity bypass of deny rules, unverified ACME certificate identities and plugin code execution from snapshots.

Safeguard Security Team
6 min read

On 7 October 2026 HashiCorp published four Vault security bulletins, HCSEC-2026-40 to HCSEC-2026-43, all fixed in Vault Community Edition 2.1.2 and Vault Enterprise 2.1.2, 1.21.12, 1.20.17 and 1.19.23. The one most teams should read first is CVE-2026-89322: Vault checked ACL policies against names as typed in the request, while the backend later normalized them, so a different letter case could slip past an explicit deny rule.

None of the four needs an unauthenticated attacker. Each needs a delegated user, an operator or an ACME client. That's normal for Vault, where the interesting attacks come from people who already have some access.

What's affected

BulletinCVEProductIssue
HCSEC-2026-43CVE-2026-89322Community and Enterprise, up to 2.1.1ACL rules evaluated on non-canonical names, so mixed case or whitespace bypasses specific deny rules and denied_parameters
HCSEC-2026-40CVE-2026-105818Community and Enterprise, 1.14.0 to 2.1.1PKI ACME sign-verbatim default policy copies unverified SAN types into issued certificates
HCSEC-2026-41CVE-2026-105816Community and Enterprise, up to 2.1.1Plugin catalog entries restored from a Raft snapshot can point outside the plugin directory and run as the Vault user
HCSEC-2026-42CVE-2026-105820Enterprise only, up to 2.1.1Policy names with path traversal resolve policies from other namespaces through the cache

Fixed versions: Community 2.1.2. Enterprise 2.1.2, 1.21.12, 1.20.17 and 1.19.23.

The deny bypass. Vault policies often combine a broad allow, such as managing all roles under an auth method, with a more specific deny for one sensitive role. Many Vault components treat names as case-insensitive. Policy evaluation used the name as supplied, while the component later lowercased it or trimmed whitespace. So a request for Admin-Role didn't match the deny on admin-role, and was then applied to admin-role. The bulletin gives examples: getting credentials for an explicitly denied auth method role, or assigning an explicitly denied policy to a token, role, user or identity. Enterprise Sentinel policies on the request path were affected the same way.

The ACME issue. Vault's ACME server validates DNS names and IP addresses through challenges. Under the default sign-verbatim directory policy, Vault also copied other SAN types from the CSR into the certificate, unverified. A client that proved control of one name could get a certificate that also asserted other identities.

The plugin issue. Vault checked that a plugin binary sat inside plugin_directory at registration time but not when a stored catalog entry was later run. A restored Raft snapshot could carry an entry pointing anywhere, and Vault would run that binary, including during unseal. It requires a privileged operator who can restore snapshots, a Shamir seal, and a configured plugin directory.

How to check if you're exposed

Version and seal type:

vault status | grep -E "Version|Seal Type"

Find policy rules that use uppercase letters in paths. These are the rules that will stop matching after the upgrade:

for p in $(vault policy list); do
  vault policy read "$p" | grep -nE '^path "[^"]*[A-Z]' | sed "s|^|$p: |"
done

Also list policies that use denied_parameters on policy names, since that pattern is called out in the bulletin:

for p in $(vault policy list); do
  vault policy read "$p" | grep -q denied_parameters && echo "$p"
done

For each PKI mount with ACME, check the directory policy:

vault read pki/config/acme

If enabled is true and default_directory_policy is sign-verbatim (or unset), the mount is affected.

On Enterprise, look for policy names with . or .. path segments, which 2.1.2 will reject and ignore:

vault policy list -namespace=admin | grep -E '(^|/)\.\.?(/|$)'

What to do now

  1. Upgrade every node, including standbys and, on Enterprise, performance and DR secondaries. HCSEC-2026-41 calls this out explicitly.
  2. Rewrite mixed-case policy rules in lowercase before upgrading. After 2.1.2, ACL and Sentinel rules for affected resources are evaluated against the lowercase name, so a deny rule on Admin-Role would stop matching anything. Do this first or you'll open the hole you meant to close.
  3. Know the gaps that remain. The bulletin says the Okta, LDAP and RADIUS auth methods and Enterprise SCIM clients are not covered by the fix. For those, avoid combining broad allow rules with narrower deny rules.
  4. Fix ACME mounts now if you can't upgrade. Point the default directory policy at a role that restricts SAN types, or disable the default directory. After upgrading, sign-verbatim rejects unverified SAN types, and a new sign-verbatim-unsafe value restores the old behavior if you truly need it.
  5. Re-register out-of-tree plugins. After upgrading, catalog entries resolving outside the plugin directory are refused and their mounts skipped at startup. Move those binaries into the plugin directory and register them again.
  6. Rename Enterprise policies with . or .. segments before upgrading. Afterwards they are ignored for existing tokens and identities, which can quietly reduce permissions.

Why it matters

The deny bypass is a classic check-then-use mismatch. The authorizer and the backend each had a reasonable idea of what a name was, and they disagreed. It also shows why "allow broadly, deny specifically" is fragile in any policy language. An allowlist of what a delegated admin may touch fails closed when names don't match, and a denylist fails open.

The other three bulletins share a pattern too: an input trusted because of where it came from. ACME trusted the CSR beyond what the challenge proved. The plugin runner trusted the catalog because registration had checked it once. Snapshots, CSRs and restored state deserve the same validation as live requests.

Try it yourself

Pick one delegated admin policy that pairs a wildcard allow with a specific deny. In a dev Vault on your current version, try the denied action using different letter case in the resource name and note the result. Then rewrite the policy as an explicit allowlist and repeat the test on 2.1.2.

Quick check

Is Vault Community Edition affected by the namespace policy cache bug, CVE-2026-105820?

No. Namespaces are an Enterprise feature, so Community is not affected, although 2.1.2 includes the same changes as hardening.

Why should you rewrite mixed-case deny rules before upgrading?

After 2.1.2, ACL and Sentinel policies for affected resources are evaluated against the lowercase resource name. A rule that names a resource with capital letters will no longer match, including deny rules.

Which deployments are exposed to the plugin catalog code execution issue?

Clusters using Shamir seals with an external plugin directory configured, where a privileged operator can restore Raft snapshots. Auto-unseal clusters and clusters without a plugin directory are not affected.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.