Mar 3, 2026·6 min read·19 visits
OpenClaw versions before 2026.1.29 are vulnerable to arbitrary file reads. Attackers can create malicious symbolic links in an agent's workspace (e.g., naming a link 'avatar.png' that points to '/etc/passwd'). The system follows these links during avatar resolution, exposing sensitive host files.
A symbolic link traversal vulnerability exists in the OpenClaw AI assistant platform, specifically within the agent avatar resolution logic. This flaw allows attackers with write access to an agent's workspace to create symbolic links pointing to arbitrary files on the host filesystem. When the gateway attempts to serve or process the agent's avatar, it follows the symbolic link and discloses the target file's contents, bypassing workspace isolation boundaries. The vulnerability also includes a Time-of-Check Time-of-Use (TOCTOU) race condition.
The vulnerability affects the OpenClaw gateway, a component responsible for managing AI agent sessions and serving user interface assets. OpenClaw assigns a local workspace directory to each agent where it can store files, including identity assets like avatars. The flaw resides in how the gateway resolves and serves these avatar images.
Specifically, the resolveIdentityAvatarUrl function and the avatar-serving endpoints failed to properly validate the destination of symbolic links. While the application verified that the requested file path string was nominally within the workspace directory, it did not resolve symbolic links before reading the file content. This allowed the filesystem APIs to transparently follow links pointing outside the restricted workspace root.
This is a classic Link Following vulnerability (CWE-59) combined with Improper Limitation of a Pathname to a Restricted Directory (CWE-22). It permits an attacker who can influence workspace content to read any file the OpenClaw process has permission to access, compromising the confidentiality of the host system.
The root cause is twofold: reliance on path string validation instead of canonical path validation, and the presence of a Time-of-Check Time-of-Use (TOCTOU) race condition.
1. Inadequate Path Validation:
The original implementation used path.resolve to normalize the requested file path and checked if the resulting string started with the workspace root path. However, standard path resolution logic in Node.js does not expand symbolic links. If an attacker created a link at /workspace/avatar.png pointing to /etc/passwd, the path string /workspace/avatar.png would arguably pass the containment check. When fs.readFileSync was subsequently called, the operating system resolved the link and returned the contents of /etc/passwd.
2. TOCTOU Race Condition:
The code performed a check using fs.statSync to verify file properties (such as size) before calling fs.readFileSync. These are distinct system calls. In the window between stat and read, an attacker could swap a valid image file with a symbolic link. The initial check would validate the safe file, but the read operation would target the malicious link, bypassing security controls.
The remediation involved shifting from path-based operations to file descriptor (FD) operations to eliminate race conditions and enforcing canonical path checks.
Vulnerable Logic (Conceptual):
// src/gateway/session-utils.ts (Pre-patch)
const avatarPath = path.join(workspaceRoot, 'avatar.png');
if (isPathWithinRoot(avatarPath, workspaceRoot)) {
// VULNERABLE: fs.stat followed by fs.readFile creates a race condition
// and fs.readFile follows symlinks by default.
const stats = fs.statSync(avatarPath);
if (stats.size < MAX_SIZE) {
const data = fs.readFileSync(avatarPath); // Follows symlink!
return createDataUrl(data);
}
}Patched Logic:
The fix introduces strict identity verification. The code now opens the file first to obtain a file descriptor, then performs checks on that specific descriptor. It also compares the file's identity (inode and device ID) from lstat (link-aware) and fstat (descriptor-aware) to ensure no swapping occurred.
// src/gateway/session-utils.ts (Patched)
import * as fs from 'fs';
// 1. Resolve the canonical path of the root to prevent traversal via root parents
const realRoot = fs.realpathSync(workspaceRoot);
// 2. Open file with O_NOFOLLOW to fail if the immediate path component is a link
// (Note: Node.js fs.openSync flags depend on platform, but logic enforces no-follow semantics)
const fd = fs.openSync(avatarPath, 'r');
try {
// 3. Verify file identity to prevent TOCTOU
const linkStats = fs.lstatSync(avatarPath);
const fdStats = fs.fstatSync(fd);
if (linkStats.ino !== fdStats.ino || linkStats.dev !== fdStats.dev) {
throw new Error('File identity mismatch (possible symlink swap)');
}
// 4. Verify canonical path containment
const realPath = fs.realpathSync(avatarPath);
if (!realPath.startsWith(realRoot)) {
throw new Error('Path traversal detected');
}
// 5. Safe read using the verified file descriptor
const buffer = Buffer.alloc(fdStats.size);
fs.readSync(fd, buffer, 0, fdStats.size, 0);
} finally {
fs.closeSync(fd);
}To exploit this vulnerability, an attacker must have the ability to create files within the agent's workspace. This is often achievable if the agent exposes file upload capabilities or if the attacker has compromised a lower-privileged component with workspace access.
Step 1: Workspace Access
The attacker gains access to the agent's workspace directory, typically located at ~/.openclaw/workspace/.
Step 2: Malicious Symlink Creation
The attacker deletes the legitimate avatar.png and replaces it with a symbolic link pointing to a sensitive system file.
# Target the system password file
ln -sf /etc/passwd ~/.openclaw/workspace/avatar.pngStep 3: Trigger Resolution
The attacker triggers an avatar refresh or navigates to the control interface where the avatar is displayed. The OpenClaw gateway receives a request to /avatar/{agentId} or calls resolveIdentityAvatarUrl internally.
Step 4: Data Exfiltration
The server reads the target of the symlink (/etc/passwd). If the endpoint returns a data URL, the attacker receives a Base64 string:
data:image/png;base64,cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaAo...
Decoding this string reveals the content of the compromised file.
This vulnerability poses a confidentiality risk. While it does not directly allow arbitrary code execution, the ability to read arbitrary files can lead to complete system compromise depending on the files accessible to the OpenClaw process.
Critical Assets at Risk:
config.json or .env files could expose API keys, database credentials, or third-party service tokens./etc/passwd (user enumeration) or SSH keys (if permissions allow) could facilitate lateral movement.The severity is mitigated by file permissions; the attacker can only read files that the user running the OpenClaw process can read. If OpenClaw runs as root (against best practices), the impact is critical. If it runs as a dedicated low-privilege user, the impact is limited to that user's access scope.
The vulnerability is fixed in OpenClaw version 2026.1.29. All users should upgrade immediately.
Primary Fix:
Upgrade to the patched version which implements fs.openSync with file descriptor checks and strict canonical path verification (fs.realpathSync) to prevent symlink traversal.
Defensive Configuration:
# Example audit command
find /path/to/openclaw/workspaces -type l -lsCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenClaw OpenClaw | < 2026.1.29 | 2026.1.29 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-59 (Link Following) |
| Attack Vector | Local / Remote (via Workspace) |
| CVSS Score | 6.6 (Medium) |
| Impact | Confidentiality Loss (Arbitrary File Read) |
| Exploit Status | PoC Available |
| Platform | Node.js / TypeScript |
Improper Link Resolution Before File Access ('Link Following')
A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.
CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.
The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.
GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.
The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.
The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.