CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-47Q7-97XP-M272

GHSA-47Q7-97XP-M272: Cleartext Credential Exposure via Configuration Persistence in OpenClaw

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 3, 2026·6 min read·26 visits

Executive Summary (TL;DR)

Running maintenance commands like `openclaw doctor` or `update` silently replaces secure environment variable placeholders (e.g., `${KEY}`) in your config file with the actual cleartext secret values, permanently writing them to disk.

A critical information disclosure vulnerability exists in the OpenClaw AI assistant's configuration management subsystem. When processing configuration files that utilize environment variable interpolation (e.g., `${API_KEY}`), certain write operations—such as updates or repairs—inadvertently resolve these references to their runtime values and persist the cleartext secrets back to the disk. This effectively converts ephemeral, secure configuration references into permanent, plaintext credentials stored within `openclaw.json`, significantly increasing the risk of accidental secret leakage via version control or backup mechanisms.

Vulnerability Overview

The OpenClaw personal AI assistant supports a security best practice known as configuration interpolation, allowing users to reference environment variables in their openclaw.json file using the syntax ${VAR_NAME}. This ensures that sensitive secrets, such as LLM provider API keys (OpenAI, Anthropic) or bot tokens, remain in memory or environment files and are never written to static configuration storage.

However, a regression in the configuration I/O logic breaks this security model. When the application performs operations that require reading, modifying, and saving the configuration—specifically during automated updates, interactive configuration (openclaw configure), or self-healing routines (openclaw doctor --fix)—it fails to distinguish between the resolved runtime value and the original configuration source.

Consequently, the application overwrites the user's secure configuration file with the resolved in-memory state. A placeholder like ${OPENAI_API_KEY}, which is safe to check into version control, is replaced by the actual alphanumeric secret key sk-proj-..., which is strictly confidential. This transformation happens silently, often without the user's knowledge, until the file is inspected or inadvertently committed to a public repository.

Technical Root Cause Analysis

The vulnerability resides in the configuration serialization pipeline located in src/config/config-io.ts. The root cause is a lack of separation between the canonical configuration (what is stored on disk) and the effective configuration (what is used in memory).

When OpenClaw initializes, it invokes a loader that parses the JSON file and immediately passes it through a resolution function, resolveConfigEnvVars. This function recursively walks the object tree and substitutes any string matching the pattern ${...} with the corresponding value from process.env. The resulting object is used by the application for all logic.

The critical flaw occurs in the writeConfigFile function. This function accepts the current configuration object state to save changes to disk. Because the application only maintains the resolved state in memory without keeping a reference to the original raw state or a map of interpolated fields, JSON.stringify serializes the actual secret values. The serialization logic assumes that the current value of a field is the desired persistent value, ignoring the fact that the value originated from an ephemeral environment source.

Vulnerable Code Analysis

The following pseudo-code illustrates the logic flow responsible for the vulnerability. The application loads the config, interpolates it immediately, and then writes that interpolated version back to disk during updates.

Vulnerable Logic (src/config/config-io.ts)

// LOAD: Reads JSON and immediately destroys the reference to "${VAR}"
function loadConfig() {
  const raw = fs.readFileSync('openclaw.json', 'utf8');
  const config = JSON.parse(raw);
  // Vulnerability: Original formatting is lost here
  return resolveEnvVars(config);
}
 
// SAVE: Writes the resolved values (secrets) to disk
function saveConfig(updatedConfig) {
  // Vulnerability: Writes "sk-12345..." instead of "${API_KEY}"
  const output = JSON.stringify(updatedConfig, null, 2);
  fs.writeFileSync('openclaw.json', output);
}

Patched Logic (Conceptual)

The fix, introduced in PR #4900, implements a mechanism to preserve the original interpolation syntax. It likely involves tracking which fields contained variables or performing a reverse-lookup against the original raw configuration before saving.

function saveConfig(updatedConfig, originalRawConfig) {
  const outputConfig = clone(updatedConfig);
  
  // FIX: Restore ${VAR} references for fields that haven't changed logically
  for (const key of Object.keys(originalRawConfig)) {
    if (isInterpolated(originalRawConfig[key])) {
       // Revert the resolved value back to the placeholder
       outputConfig[key] = originalRawConfig[key];
    }
  }
  
  fs.writeFileSync('openclaw.json', JSON.stringify(outputConfig, null, 2));
}

Exploitation & Reproduction

Exploitation of this vulnerability is trivial and often accidental, triggered by standard maintenance commands. An attacker with local access could trigger this to persist ephemeral secrets, or a user could trigger it unknowingly.

Reproduction Steps:

  1. Setup: Create an openclaw.json file utilizing environment variable interpolation for a sensitive field.

    {
      "llm": {
        "provider": "anthropic",
        "apiKey": "${ANTHROPIC_API_KEY}"
      }
    }
  2. Environment: Export the corresponding secret in the current shell.

    export ANTHROPIC_API_KEY="sk-ant-api03-sensitive-secret-value"
  3. Trigger: Execute a command that modifies configuration. The doctor command with the --fix flag is a reliable trigger as it attempts to normalize the configuration structure.

    openclaw doctor --fix
  4. Verification: Inspect the file content. The placeholder is gone, replaced by the plaintext secret.

    cat openclaw.json
    # Output: "apiKey": "sk-ant-api03-sensitive-secret-value"

Impact Assessment

The primary impact of this vulnerability is the Unintentional Exposure of Sensitive Information (CWE-200) and Cleartext Storage of Sensitive Information (CWE-312). While the vulnerability requires local execution to trigger, the downstream effects can be severe in DevOps and collaborative environments.

  • Version Control Leakage: Configuration files are frequently checked into Git repositories. If a developer runs a local update and then commits the changes (git commit -am "update config"), they may unknowingly push live production credentials to a shared or public repository.
  • Persistence of Ephemeral Secrets: Security best practices dictate that secrets should exist only in memory or restricted environment files. This vulnerability violates that principle by writing secrets to the filesystem, where they are vulnerable to path traversal attacks, insecure backups, or unauthorized local read access.
  • Silent Failure: The modification happens silently. There is no error message indicating that interpolation has been stripped, meaning the exposure may persist undetected for long periods.

Remediation

Users must upgrade OpenClaw immediately to prevent further exposure. If you have run any maintenance commands on affected versions, your secrets may already be exposed on disk.

Immediate Steps:

  1. Upgrade: Update OpenClaw to version v2026.2.7 or later. This version includes the fix from PR #4900 which correctly handles environment variable preservation.
  2. Audit: Run grep -r "sk-" openclaw.json or manually inspect your configuration file to verify no cleartext secrets are present.
  3. Rotate: If you discover cleartext secrets in your configuration file, assume they are compromised. Revoke the API keys immediately and generate new ones.
  4. Sanitize: Revert the configuration file to use ${VAR} syntax manually.

Long-term Hardening: Ensure that openclaw.json is added to your .gitignore file if it contains any specific local configuration, or strictly use separate environment files (e.g., .env) that are never tracked.

Fix Analysis (1)

Technical Appendix

CVSS Score
7.4/ 10
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:N/A:N
EPSS Probability
0.04%

Affected Systems

OpenClaw Personal AI AssistantOpenClaw CLI Tools

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenClaw
OpenClaw
<= v2026.2.6-3v2026.2.7
AttributeDetail
CWE IDCWE-312
Vulnerability TypeInformation Disclosure
Attack VectorLocal / File System
ImpactConfidentiality Loss
Affected ComponentConfig I/O (openclaw.json)
CVSS Score7.4 (High)

MITRE ATT&CK Mapping

T1552.001Unsecured Credentials: Credentials In Files
Credential Access
CWE-312
Cleartext Storage of Sensitive Information

The application stores sensitive information in cleartext within a resource that might be accessible to another control sphere.

Vulnerability Timeline

Fix PR #4900 Merged
2026-02-07
Patch Release v2026.2.7
2026-02-08

References & Sources

  • [1]GHSA-47Q7-97XP-M272 Advisory
  • [2]PR #4900: Fix config write paths

More Reports

•about 4 hours ago•CVE-2026-92945
4.2

CVE-2026-92945: Sandbox Escape and Module Allowlist Bypass via Path Prefix Matching in vm2

A module allowlist bypass vulnerability (CVE-2026-92945 / GHSA-7q3f-wx44-378m) was identified in the vm2 sandboxing library prior to version 3.11.7. This flaw permits unauthenticated or untrusted code running within the sandbox environment to bypass explicit module restrictions. When the transitive resolution option is disabled, the system fails to validate file system path boundaries, allowing prefix-sharing sibling directories to be resolved and loaded, thereby escaping intended sandbox restrictions.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 5 hours ago•CVE-2026-92941
10.0

CVE-2026-92941: Sandbox Escape and Process-Wide TLS Trust Store Manipulation in vm2

CVE-2026-92941 is a critical sandbox-escape and trust-manipulation vulnerability in the vm2 library (versions 3.11.3 to 3.11.6). This security flaw allows untrusted code executing within a NodeVM sandbox environment to compromise the global TLS trust store of the host Node.js process. By leveraging a design flaw where the host's native 'tls.setDefaultCACertificates' can be executed via a proxy wrapper, combined with a bridge unwrapping bypass in the 'url' module, an attacker can modify the process-wide default root Certificate Authorities. Consequently, all subsequent outbound TLS/HTTPS clients running on the host thread are forced to trust attacker-signed certificates, facilitating transparent Man-in-the-Middle (MitM) attacks. The vulnerability was resolved in version 3.11.7 of vm2 by introducing built-in member-level sanitization before applying read-only proxy wrappers.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 6 hours ago•CVE-2026-92944
9.8

CVE-2026-92944: Sandbox Escape in vm2 via Stale V8 PromiseThenLookupChain Protector

A critical engine-level reachability failure in Node.js 26 running V8 14.6 allows attackers to escape the vm2 sandbox environment. When consecutive prototype properties are modified using sequential assignments, a V8 optimization bug fails to invalidate the PromiseThenLookupChain protector. By calling Promise.prototype.finally, the attacker bypasses the vm2 wrappers, hijacks the promise reaction using a custom constructor, triggers a calibrated stack overflow to capture a host-realm RangeError, and executes arbitrary shell commands on the host.

Alon Barad
Alon Barad
7 views•8 min read
•about 7 hours ago•CVE-2026-92939
9.9

CVE-2026-92939: Critical Sandbox Escape via Host Crypto setEngine Native Code Execution in vm2

A critical sandbox escape vulnerability in the vm2 library allows sandboxed JavaScript code to bypass containment and execute arbitrary native code on the host process. This occurs when the host's builtin crypto module is exposed to the NodeVM environment. Although vm2 implements a read-only proxy layer to restrict direct modifications to host properties, it does not prevent invocation of host-level functions. By calling the crypto.setEngine API with a path to a malicious native library on disk, an attacker can trigger OpenSSL's dynamic module loader. The host's operating system loader immediately runs the dynamic library's initializers/constructors before verifying engine compatibility, leading to remote code execution in the context of the host process.

Amit Schendel
Amit Schendel
6 views•5 min read
•about 8 hours ago•CVE-2026-92938
9.9

CVE-2026-92938: Remote Code Execution in vm2 via node:sqlite DatabaseSync Sandbox Escape

CVE-2026-92938 is a critical sandbox escape vulnerability in the vm2 library (versions 3.11.3 through 3.11.6) that allows arbitrary native code execution on the host when the node:sqlite built-in module is loaded inside a sandboxed NodeVM environment.

Amit Schendel
Amit Schendel
8 views•8 min read
•about 9 hours ago•CVE-2026-92937
10.0

CVE-2026-92937: Sandbox Escape leading to Remote Code Execution via Promise Indirection in vm2

CVE-2026-92937 is a critical sandbox escape vulnerability in the `vm2` Node.js library. Due to a logical failure in checking direct invocation targets inside the Proxy bridge, an attacker can register Promise callbacks using `Function.prototype.call` or `Function.prototype.apply` indirection. This bypasses the error sanitization wrappers, delivering raw host error objects directly to sandboxed callbacks and allowing the attacker to escape the sandbox and execute arbitrary shell commands on the host.

Amit Schendel
Amit Schendel
8 views•6 min read