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-6C9J-X93C-RW6J
4.30.04%

OpenClaw Side-Channel: The `safeBins` File Existence Oracle

Alon Barad
Alon Barad
Software Engineer

Feb 20, 2026·6 min read·8 visits

PoC Available

Executive Summary (TL;DR)

OpenClaw tried to stop AI agents from reading sensitive files by checking if files existed before running commands. Ironically, this check created a side-channel: if the system blocked the command, the attacker knew the file existed. If it didn't, the file was missing.

A logic flaw in the OpenClaw AI agent framework's command validation layer created a boolean side-channel, allowing attackers to probe the host filesystem. By attempting to prevent agents from accessing sensitive files via 'safe' binaries, the validation logic inadvertently revealed the existence of those files through error message discrepancies.

The Hook: Safety is a Double-Edged Sword

In the brave new world of Agentic AI, we want our digital minions to be capable but not too capable. We give them tools—specifically, shell access. But giving an LLM raw bash access is usually a résumé-generating event for security teams. So, frameworks like OpenClaw implement a concept called safeBins.

The idea is simple: allow the agent to run benign utilities like grep, sort, jq, and sed, but wrap them in a warm blanket of validation logic to ensure they aren't used to exfiltrate /etc/shadow or nuke the filesystem. It’s the 'sandbox' approach to shell execution.

However, in OpenClaw versions prior to 2026.2.19, this safety blanket had a hole in it. The mechanism designed to prevent the agent from touching sensitive files actually gave the agent a flashlight to find them. It turns out that when your security check involves asking the operating system, "Does this secret file exist?" and then acting differently based on the answer, you've just built a classic Oracle.

The Flaw: The Boolean Oracle

The vulnerability lies in src/infra/exec-approvals-allowlist.ts. The developers wanted to ensure that when an agent calls a binary like grep, it isn't pointing it at a sensitive file on the disk. To achieve this, they implemented a check that iterates through every token in the command's argument list (argv).

Here is where the logic went sideways. The validator used a helper function, essentially a wrapper around fs.existsSync, to check if an argument resolved to a real path on the host system. If the token resolved to an existing file, the validator would throw a specific error (allowlist miss) and block the execution.

Do you see the problem? It’s a boolean side-channel.

If I ask the agent to run grep pattern /etc/passwd and the system rejects it because "Wait, that's a real file!", I have confirmed the file exists. If I ask for grep pattern /etc/unicorn_tears and the system says "Command failed" (because grep couldn't find the file) or allows it to proceed, I know the file does not exist. The security mechanism itself became the very thing it was trying to prevent: a filesystem enumeration tool.

The Code: Reading the Tea Leaves

Let's look at the smoking gun. The vulnerable logic was relying on the filesystem state to make security decisions. This is a cardinal sin in secure coding—validation should be syntactic, not semantic regarding the environment state.

The Vulnerable Logic:

// Inside isSafeBinUsage loop
function defaultFileExists(filePath: string): boolean {
  try {
    return fs.existsSync(filePath);
  } catch {
    return false;
  }
}
 
// ... later in the validation loop ...
if (exists(path.resolve(cwd, token))) {
  // THE LEAK: The decision to return false (deny) depends on the disk state.
  return false;
}

The Fix (Commit bafdbb6f112409a65decd3d4e7350fbd637c7754):

The patch, authored by Peter Steinberger, rips out the fs.existsSync dependency entirely. Instead of asking the disk, it parses the command arguments deterministically. It introduces SAFE_BIN_PROFILES—strict definitions for each binary that dictate exactly which flags are allowed (e.g., blocking -f in grep or -o in sort) and how many positional arguments can be passed.

// The new approach: Deterministic parsing
const profile = SAFE_BIN_PROFILES[binaryName];
 
// Blocked flags are rejected regardless of what follows them
if (profile.blockedFlags.has(arg)) {
  return false;
}
 
// Positional arguments are counted, not checked against the disk
if (!arg.startsWith("-")) {
  positionalCount++;
  if (positionalCount > profile.maxPositional) {
    return false;
  }
}

By moving to a syntax-based allowlist, the response is now constant regardless of whether /secret/config.json actually exists.

The Exploit: Knocking on Doors

Exploiting this is trivially easy for anyone controlling the agent's input or instructions. We don't need memory corruption; we just need to observe the error messages. Let's assume we want to map out the server's directory structure.

Step 1: Calibration First, we establish our baseline responses.

  • Probe: sort /etc/passwd (We know this exists on Linux)

  • Response: Error: Execution denied: allowlist miss (The Oracle confirms existence)

  • Probe: sort /etc/does_not_exist_12345

  • Response: Error: Command failed (or a generic execution error because sort ran and failed)

Step 2: The Attack Now we script the agent to brute-force interesting paths.

const targets = [
  "/root/.ssh/id_rsa",
  "/home/user/.aws/credentials",
  "/var/run/docker.sock",
  "/proc/1/environ"
];
 
for (const target of targets) {
  const result = await agent.exec(`grep -l foo ${target}`);
  if (result.error.includes("allowlist miss")) {
    console.log(`[+] FOUND: ${target}`);
  } else {
    console.log(`[-] MISS:  ${target}`);
  }
}

This allows an attacker to perform reconnaissance without ever successfully executing a command against a file. It's akin to a blind SQL injection, but for the filesystem.

The Impact: Why This Matters

You might look at the CVSS score of 4.3 and think, "Meh, it's just information disclosure." And sure, on its own, knowing a file exists isn't the same as reading it. But in the context of an attack chain, reconnaissance is king.

Knowing exactly where the config.json lives, or confirming the presence of a specific Docker socket, or determining which version of a library is installed by probing for version-specific files, allows an attacker to tailor their next stage payload with precision.

Furthermore, this vulnerability exposes the presence of security tools, logs, or other artifacts that an attacker might want to avoid or target. In a containerized environment, mapping the filesystem is often step one in a container breakout. The oracle provided by OpenClaw was a free map.

The Fix: Determinism is Key

The mitigation is straightforward: Update OpenClaw to version 2026.2.19 or later. The fix changes the validation philosophy from "Check the world" to "Check the syntax."

If you are building your own command execution validators, take this as a lesson: Never use environmental state (file existence, network reachability, user presence) as a condition for input validation if the failure state is visible to the user. It will always leak information.

Instead, use strict allowlists for arguments. If grep supports a -f flag that reads a file, don't check if the file exists—just ban the -f flag entirely if you don't want files being read. Syntax is predictable; the filesystem is not.

Official Patches

OpenClawGitHub Commit: Remove fs check from validator

Fix Analysis (1)

Technical Appendix

CVSS Score
4.3/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

OpenClaw Framework (npm package `openclaw`)AI Agents utilizing the `safeBins` execution tool

Affected Versions Detail

Product
Affected Versions
Fixed Version
openclaw
OpenClaw
<= 2026.2.172026.2.19
AttributeDetail
CWE IDCWE-203
Attack VectorNetwork (Agent Session)
CVSS4.3 (Medium)
RiskFilesystem Enumeration
ImpactInformation Disclosure
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1592Gather Victim Host Information
Reconnaissance
CWE-203
Information Exposure through Discrepancy

Observable Discrepancy

Known Exploits & Detection

Researcher AnalysisManual reconstruction of the boolean oracle based on patch diff.
NucleiDetection Template Available

Vulnerability Timeline

Vulnerability reported by @nedlir
2026-02-19
Patch authored by Peter Steinberger
2026-02-19
GHSA-6c9j-x93c-rw6j Published
2026-02-19

References & Sources

  • [1]GHSA Advisory
  • [2]OSV Record

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.