Apr 29, 2026·7 min read·8 visits
OpenClaw versions before 2026.4.15 are vulnerable to a Local File Read flaw in the gateway component. Missing path containment checks in the audio embedding logic allow attackers to read arbitrary files from the filesystem by supplying crafted media URLs.
The OpenClaw gateway component prior to version 2026.4.15 contains a Local File Read (LFR) vulnerability due to improper restriction of pathnames to authorized directories. The flaw resides in the webchat audio embedding functionality, which fails to restrict local file resolution to a trusted sandbox directory. An attacker who can influence the media URL of an agent reply can extract arbitrary local files that bypass extension and size filters, exposing sensitive data to the web interface.
The OpenClaw gateway acts as the primary intermediary for processing agent replies and handling media assets requested by the webchat interface. A core feature of this component is the ability to embed audio files directly into webchat responses. When an agent or command reply references a media asset, the gateway resolves the provided file path, reads the file from the local disk, and base64-encodes the content for inline transmission to the client.
This architecture introduces a significant attack surface if the underlying path resolution logic is flawed. The vulnerability, tracked as GHSA-GFG9-5357-HV4C, manifests as an Improper Limitation of a Pathname to a Restricted Directory (CWE-22). The specific failure occurs because the gateway attempts to process absolute paths and file:// URIs without verifying that the resolved path resides within an explicitly authorized media root directory.
By leveraging this flaw, an attacker can manipulate the application into accessing files outside the intended operational scope. The application retrieves the targeted file, processes it through the standard base64 encoding pipeline, and delivers the encoded data directly to the webchat interface. This mechanism provides a direct exfiltration vector for local system data, constrained only by internal file size limits and extension verification checks.
The vulnerability originates in the src/gateway/server-methods/chat-webchat-media.ts file, specifically within the resolveLocalAudioFileForEmbedding function and its associated helper resolveLocalMediaPathForEmbedding. The root cause is the reliance on unconstrained path resolution functions combined with the absence of directory traversal prevention measures.
When a mediaUrl payload is received, the code utilizes the Node.js path.resolve() method to convert the input into an absolute path. Node.js path.resolve() normalizes paths and resolves directory traversals (../), but it does not intrinsically restrict the resulting absolute path to a specific base directory. Following resolution, the application enforces two checks: an extension check to ensure the file ends with a supported audio format (e.g., .mp3, .wav) and a size check against MAX_WEBCHAT_AUDIO_BYTES.
The critical missing component is a containment boundary check. The application fails to verify whether the final resolved path is a child of the configured media storage directory. Consequently, supplying an absolute path like /tmp/outside/sensitive_data.mp3 or a traversal payload like ../../../../var/lib/data.mp3 bypasses the intended directory restrictions. The application blindly trusts the resolved path as long as it satisfies the extension and size criteria.
An analysis of commit 6e58f1f9f54bca1fea1268ec0ee4c01a2af03dde details the transition from the vulnerable implementation to the secure, patched logic. The vulnerable code executed path resolution synchronously and relied entirely on superficial checks without validating the filesystem boundary.
The patch introduces a robust containment model utilizing a new security primitive: assertLocalMediaAllowed(). This function is responsible for ensuring that the resolved absolute path is strictly a descendant of the configured localRoots. If the path escapes these boundaries, the assertion fails, and the read operation is terminated immediately.
// Conceptual representation of the fix in chat-webchat-media.ts
// BEFORE PATCH (Vulnerable)
export function resolveLocalAudioFileForEmbedding(mediaUrl: string) {
const resolved = path.resolve(mediaUrl);
if (!isValidAudioExtension(resolved)) return null;
if (getFileSize(resolved) > MAX_WEBCHAT_AUDIO_BYTES) return null;
return encodeToBase64(resolved);
}
// AFTER PATCH (Secure)
export async function resolveLocalAudioFileForEmbedding(mediaUrl: string, options: MediaOptions) {
const resolved = path.resolve(mediaUrl);
// Security Boundary Check Added
assertLocalMediaAllowed(resolved, options?.localRoots);
if (!isValidAudioExtension(resolved)) return null;
if (getFileSize(resolved) > MAX_WEBCHAT_AUDIO_BYTES) return null;
return encodeToBase64(resolved);
}Furthermore, the patch implements getAgentScopedMediaLocalRoots. This ensures that directory access restrictions are applied per-agent, providing defense-in-depth. If one agent is compromised or manipulated, it cannot access media assets explicitly restricted to another agent's workspace. The transition to an asynchronous architecture was necessary to support these enhanced validation routines, as checking agent scopes requires asynchronous context resolution.
Exploiting this vulnerability requires the attacker to fulfill specific prerequisites. The attacker must possess the ability to inject or modify the mediaUrl field within an agent reply or command payload. The system processes this payload and triggers the vulnerable resolveLocalAudioFileForEmbedding routine.
The primary hurdle for exploitation is the extension check. The application verifies that the target file ends with an accepted audio extension. An attacker cannot read generic system files like /etc/passwd directly unless they can control the filename or manipulate the environment to append the required extension. Attackers often bypass this restriction by exploiting predictable temporary file patterns, symlinks, or by renaming sensitive files prior to extraction if they have limited write access.
The official test suite provides an operational Proof-of-Concept for the exploit mechanics. By defining a mediaUrl pointing to an absolute path outside the intended directory, the test confirms that the application previously embedded the file contents.
// Test suite PoC demonstrating the vulnerability context
it("rejects a local audio file outside configured localRoots", async () => {
const allowedRoot = "/tmp/allowed";
const outsideRoot = "/tmp/outside";
// Attacker crafts a path outside the permitted directory boundary
const audioPath = "/tmp/outside/sensitive_data.mp3";
const blocks = await buildWebchatAudioContentBlocksFromReplyPayloads(
[{ mediaUrl: audioPath }],
{ localRoots: [allowedRoot] }
);
// In vulnerable versions, blocks contained the base64 encoded data.
// The patched version correctly returns 0 blocks.
expect(blocks).toHaveLength(0);
});The vulnerability constitutes an information disclosure vector via Local File Read (LFR). When exploitation is successful, the targeted file is read into memory, base64-encoded, and delivered to the webchat client. This encoding guarantees the clean exfiltration of both binary and text data without interference from string processing routines or network firewalls.
The impact severity is bounded by the file extension and size constraints. The requirement for specific extensions (.mp3, .wav, etc.) prevents untargeted, opportunistic reading of arbitrary configuration files unless the attacker has secondary mechanisms to manipulate the file system. The size constraint (MAX_WEBCHAT_AUDIO_BYTES) further restricts the volume of data that can be exfiltrated in a single transaction, mitigating the risk of memory exhaustion or large-scale database theft.
Despite these mitigating factors, the vulnerability poses a substantial security risk in multi-tenant or shared environments. If an attacker can stage a file with the correct extension, or if sensitive application data naturally shares those extensions or is placed in predictably named temporary locations, confidentiality is broken. The CVSS score reflects this conditional impact, classifying the vulnerability as Medium severity.
The definitive remediation for this vulnerability is updating OpenClaw to version 2026.4.15 or later. The patch deployed in commit 6e58f1f9f54bca1fea1268ec0ee4c01a2af03dde fundamentally resolves the issue by enforcing directory containment prior to any file read operations.
For environments where immediate patching is not feasible, administrators should enforce strict file system permissions on the host system. The user account executing the OpenClaw Node.js process must be granted the minimum necessary read privileges, restricted exclusively to the intended application directories. This limits the blast radius of the LFR, ensuring that even if path traversal occurs, the operating system blocks access to sensitive global files.
Developers integrating OpenClaw should additionally review their localRoots configuration. The localRoots array should be as narrow as possible, avoiding root directory / or broad parent directories /tmp. Implementing getAgentScopedMediaLocalRoots is strongly advised to enforce strict tenant isolation, preventing lateral data exposure across different agents operating within the same OpenClaw instance.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenClaw OpenClaw | < 2026.4.15 | 2026.4.15 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| Impact | Information Disclosure (Local File Read) |
| Exploit Status | Proof of Concept |
| CVSS Score | 6.5 |
| Fixed Version | 2026.4.15 |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')