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-5XFQ-5MR7-426Q
8.6

OpenClaw: When Your AI Assistant Fetches /etc/passwd

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 18, 2026·5 min read·4 visits

PoC Available

Executive Summary (TL;DR)

OpenClaw trusted user input for file paths. Attackers can use `../` in session IDs to read or write files anywhere on the host system. Fixed in v2026.2.12 via strict allowlisting and path resolution checks.

A critical Path Traversal vulnerability in OpenClaw allows attackers to escape the session directory sandbox. By manipulating the `sessionId` parameter, malicious actors can read sensitive system files or overwrite configuration files, potentially leading to Remote Code Execution (RCE). The flaw stems from unsafe usage of Node.js path manipulation functions without adequate input validation.

The Hook: Your AI Has Too Much Access

We all want our AI agents to remember us. Context is king, right? To achieve this, OpenClaw stores conversation histories as JSONL transcripts. Each user or agent gets a session, and that session gets a file on disk. Simple, efficient, and—as it turns out—dangerously implemented.

The feature in question resides in how the system handles sessionId and sessionFile. Ideally, when you ask for session user-123, the system looks inside ./sessions/user-123.jsonl. But what happens when you ask the AI to retrieve session ../../../../etc/passwd? In a secure world, the system laughs at you. In OpenClaw versions prior to v2026.2.12, the system dutifully fetches the password file and hands it over on a silver platter.

This isn't just a "read" vulnerability. Because OpenClaw agents need to write to these transcripts to store new memories, this is a full-blown filesystem compromise. If I can write to a file, I can overwrite your .env (stealing API keys) or your .ssh/authorized_keys (gaining shell access).

The Flaw: Trusting Node.js Path Logic

The root cause here is a classic developer trap: assuming path.join() is a security tool. It is not. It is a string concatenation tool that happens to know about slashes. It does not verify that the resulting path stays within a safe boundary; it simply resolves the path logically.

In src/agents/subagent-announce.ts, the code did something like this:

const transcriptPath = 
  sessionId && storePath 
    ? path.join(path.dirname(storePath), `${sessionId}.jsonl`) 
    : undefined;

If storePath is /app/data/sessions/index and sessionId is ../../../../etc/passwd, path.join resolves this to /etc/passwd.jsonl (or similar, depending on exact string handling). The developer assumed the sessionId would just be an alphanumeric string. They didn't enforce it.

This is the digital equivalent of locking your front door but leaving the doggy door wide enough for a grown human to crawl through. The code functionally said, "Take the base directory, add whatever the user gave us, and open that file."

The Code: A Tale of Two Patches

The fix, implemented by Peter Steinberger in commit 4199f9889f0c307b77096a229b9e085b8d856c26, is a beautiful example of defense-in-depth. They didn't just fix the path resolution; they nuked the possibility of bad input entirely.

Defense Layer 1: Strict Allowlisting First, they defined what a valid ID looks like. If it contains anything other than alphanumeric characters, dots, underscores, or dashes, it's rejected immediately.

export const SAFE_SESSION_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/i;

Defense Layer 2: Path Jailing Even if the regex fails (or a developer forgets to use it elsewhere), the new resolvePathWithinSessionsDir function creates a hard verify-after-resolve check. It resolves the absolute path of the destination and ensures it starts with the absolute path of the allowed directory.

function resolvePathWithinSessionsDir(sessionsDir: string, candidate: string): string {
  const resolvedBase = path.resolve(sessionsDir);
  const resolvedCandidate = path.resolve(resolvedBase, candidate.trim());
  const relative = path.relative(resolvedBase, resolvedCandidate);
  
  // The Magic Check
  if (relative.startsWith("..") || path.isAbsolute(relative)) {
    throw new Error("Session file path must be within sessions directory");
  }
  return resolvedCandidate;
}

This path.relative check is the gold standard for preventing traversal in Node.js. It asks the filesystem: "To get from A to B, do I have to go up?" If the answer is yes, it throws an error.

The Exploit: Climbing the Directory Tree

Let's weaponize this. Assuming we have access to the OpenClaw Gateway or any endpoint that triggers session retrieval or logging.

Scenario A: Reconnaissance (LFI) We want to see what environment variables the bot is using (OpenAI keys, database creds).

  1. Target: Gateway API handling session lookup.
  2. Payload: We send a request with sessionId set to ../../.env.
  3. Result: The application joins the path, opens .env, and potentially returns the content as a "chat transcript" or leaks it in an error message if the JSON parse fails but verbose logging is on.

Scenario B: Remote Code Execution (File Write) If we can trigger a "write" event (e.g., "Save this conversation"), we can achieve RCE.

  1. Target: Session save endpoint.
  2. Payload: sessionId = ../../src/pwned.ts.
  3. Content: We inject TypeScript code into the chat context that gets saved to disk.
  4. Trigger: If the application uses dynamic imports or if we overwrite a file that is loaded on server restart (like a config file or a legitimate agent file), our code executes with the privileges of the OpenClaw process.

The Fix: Upgrade or Die

If you are running OpenClaw, check your version immediately. If you are on anything prior to v2026.2.12, you are vulnerable.

Immediate Action: Upgrade to v2026.2.12. This version includes the regex validation and the path resolution safety checks.

WAF Mitigation: If you cannot upgrade right now (why?), configure your WAF or reverse proxy (Nginx/Apache) to block any URL parameters or JSON bodies containing directory traversal patterns:

  • ../
  • ..\
  • %2e%2e%2f (URL encoded)

However, WAFs are bypassable. The code fix is the only permanent solution.

Official Patches

OpenClawRelease notes for v2026.2.12 fixing the vulnerability

Fix Analysis (1)

Technical Appendix

CVSS Score
8.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

Affected Systems

OpenClaw AI Assistant (Self-Hosted)OpenClaw Gateway

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenClaw
OpenClaw
< v2026.2.12v2026.2.12
AttributeDetail
CWE IDCWE-22 (Path Traversal)
CVSS Score8.6 (High)
Attack VectorNetwork
ImpactConfidentiality, Integrity
PlatformNode.js / TypeScript

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1552.001Credentials In Files
Credential Access
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Known Exploits & Detection

Internal ResearchPoC involves sending HTTP GET requests with traversal sequences in the sessionId query parameter.

Vulnerability Timeline

Patch Developed (v2026.2.12)
2026-02-12
Commit Merged to Main
2026-02-13
Advisory Published
2026-02-13

References & Sources

  • [1]GitHub Advisory GHSA-5XFQ-5MR7-426Q
  • [2]CWE-22: Path Traversal

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.