Mar 2, 2026·5 min read·7 visits
OpenClaw's skill syncing logic fails to sanitize skill names, allowing malicious skills to write files outside the sandbox directory via path traversal characters.
A critical path traversal vulnerability exists in the OpenClaw (Moltbot) AI agent framework within its skill mirroring mechanism. The vulnerability allows a malicious actor to escape the intended sandbox environment by manipulating skill metadata. Specifically, the `syncSkillsToWorkspace` function improperly constructs file destination paths using unvalidated user input, enabling arbitrary file writes to the host filesystem.
The OpenClaw framework (also known as Moltbot) creates sandbox environments to safely execute AI "skills"—modular capabilities defined by users or third parties. A core component of this architecture is the skill mirroring mechanism, specifically the syncSkillsToWorkspace function, which copies skill source files from a repository into a designated workspace directory for execution.
A path traversal vulnerability (CWE-22) was identified in how this function handles destination paths. When syncing a skill, the system determines the target directory using metadata provided within the skill itself (specifically the name field in SKILL.md). Because this input was not validated or sanitized, a malicious skill definition could manipulate the destination path, effectively breaking out of the sandbox confinement. This flaw allows an attacker to write arbitrary files to the host system with the privileges of the OpenClaw process.
The root cause lies in the insecure concatenation of user-controlled input with a filesystem path without prior validation. The vulnerable code used the standard Node.js path.join() function to construct the destination directory for a skill. While path.join normalizes paths, it does not prevent directory traversal if the segments themselves contain traversal sequences like ../.
In the vulnerable implementation, the code extracted the name property directly from the skill's frontmatter configuration and appended it to the targetSkillsDir. A malicious actor could define a skill name such as ../../../etc/cron.d/, causing the subsequent copy operation (fsp.cp) to write files outside the intended targetSkillsDir. The application implicitly trusted that the metadata name would be a safe, valid directory name, rather than treating it as untrusted input.
Crucially, the system lacked a boundary check—such as resolving the final path and ensuring it starts with the expected root path—before performing the file operation.
The following analysis contrasts the vulnerable logic with the remediated code in src/agents/skills/workspace.ts.
Vulnerable Code: The original implementation directly joined the target directory with the potentially malicious skill name.
// src/agents/skills/workspace.ts (Pre-patch)
for (const entry of entries) {
// VULNERABILITY: entry.skill.name is user-controlled and unsanitized.
// If name is "../../escaped", dest becomes outside targetSkillsDir.
const dest = path.join(targetSkillsDir, entry.skill.name);
try {
// Recursive copy writes files to the traversal path
await fsp.cp(entry.skill.baseDir, dest, { recursive: true });
// ...
} catch (error) {
// ...
}
}Fixed Code:
The patch abandons the use of the user-defined name for filesystem operations. Instead, it derives the directory name from the source path's basename (which is local and trusted in this context) and employs a strict path resolution utility.
// src/agents/skills/workspace.ts (Patched)
function resolveSyncedSkillDestinationPath(params: {
targetSkillsDir: string;
entry: SkillEntry;
usedDirNames: Set<string>;
}): string | null {
// 1. Use filesystem basename instead of arbitrary metadata name
const sourceDirName = path.basename(params.entry.skill.baseDir).trim();
// 2. Reject suspicious directory names explicitly
if (!sourceDirName || sourceDirName === "." || sourceDirName === "..") {
return null;
}
// 3. Resolve a unique name to prevent collisions
const uniqueDirName = resolveUniqueSyncedSkillDirName(sourceDirName, params.usedDirNames);
// 4. SECURITY CHECK: resolveSandboxPath ensures the path stays inside root
// If the resulting path escapes targetSkillsDir, this throws or returns null
return resolveSandboxPath({
filePath: uniqueDirName,
cwd: params.targetSkillsDir,
root: params.targetSkillsDir,
}).resolved;
}To exploit this vulnerability, an attacker requires the ability to introduce a new skill to the OpenClaw instance. This could occur in scenarios where the agent pulls skills from a public repository or processes a user-submitted skill bundle.
Attack Steps:
SKILL.md file. In the frontmatter of this file, they set the name field to a traversal payload, e.g., name: "../../../.ssh".syncSkillsToWorkspace function.[sandbox_root]/../../../.ssh (effectively ~/.ssh on the host).authorized_keys file) to the target directory. The attacker now has SSH access to the host machine.This vector is particularly dangerous because it bypasses the primary security mechanism of the agent—the sandbox—allowing for immediate escalation from agent control to host compromise.
The impact of this vulnerability is rated High due to the potential for arbitrary file write leading to Remote Code Execution (RCE).
The vulnerability is an "Arbitrary File Write via Path Traversal" (CWE-22). In containerized environments, this might allow escaping the application directory to the container root. In non-containerized deployments, it could lead to full host compromise.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
openclaw openclaw | < 2026.2.13 | 2026.2.13 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Vulnerability Type | Path Traversal |
| Severity | High |
| Attack Vector | Network / File Input |
| Impact | Arbitrary File Write / Sandbox Escape |
| Patch Date | 2026-02-13 |
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.