GHSA-7xr2-q9vf-x4r5 OpenClaw: Symlink Traversal via IDENTITY.md appendFile in agents.create/update (Incomplete Fix for CVE-2026-32013)
SummaryThe patch for CVE-2026-32013 introduced symlink resolution and workspace boundary enforcement for `agents.files.get` and `agents.files.set`. However, two other handlers in the same file (`agents.create` and `agents.update`) still use raw `fs.appendFile` on the `IDENTITY.md` file **without any symlink containment check**. An attacker who can place a symlink in the agent workspace can hijack the `IDENTITY.md` path to append attacker-controlled content to arbitrary files on the system.DetailsIn `src/gateway/server-methods/agents.ts`, the `agents.create` handler constructs the identity path and appends agent metadata without verifying symlinks:The `agents.update` handler has the same issue at line 348-349:`fs.appendFile` follows symlinks by default. If the `IDENTITY.md` file in the workspace is a symlink pointing to a sensitive file (e.g., `/etc/crontab`, `~/.bashrc`, or `~/.ssh/authorized_keys`), calling `agents.create` will append the agent identity metadata to that file.The `ensureAgentWorkspace` function (called at line 274 before the append) uses exclusive-create mode (`flag: 'wx'`) for `IDENTITY.md`. If a symlink already exists at that path, the `EEXIST` error is silently caught, and the subsequent `fs.appendFile` follows the symlink.**Attack flow:**PoC**Prerequisites:** Docker and Python 3 installed.**Step 1: Build and start the test environment.****Step 2: Run the exploit.**This script:Plants a symlink `IDENTITY.md → /etc/target-file.txt` inside the agent workspaceCalls the `agents.create` API endpoint via HTTP POSTVerifies that the agent identity metadata was appended to `/etc/target-file.txt`**Step 3: Run the control experiment.****Step 4: Cleanup.**Log of Evidence**Exploit output:****Control output:**ImpactAn attacker who can plant a symlink in the agent workspace directory can use the `agents.create` or `agents.update` gateway API to **append attacker-controlled content to arbitrary files** on the system. If the target file is:`/etc/crontab` or user crontab → **Remote Code Execution**`~/.bashrc` or `~/.profile` → **Persistent code execution on login**`~/.ssh/authorized_keys` → **Unauthorized SSH access**Application configuration files → **Service disruption**The attacker-controlled content includes the agent name (arbitrary string), emoji, and avatar fields, which are only lightly sanitized (whitespace normalization via `sanitizeIdentityLine`).Affected products**Ecosystem**: npm**Package name**: openclaw**Affected versions**: <= 2026.2.22**Patched versions**: NoneOccurrences| Permalink | Description |
| :--- | :--- |
| [https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L283-L291](https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L283-L291) | `agents.create` handler uses `fs.appendFile` on `IDENTITY.md` without symlink resolution or workspace boundary check. |
| [https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L348-L349](https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L348-L349) | `agents.update` handler uses `fs.appendFile` on `IDENTITY.md` without symlink resolution or workspace boundary check. |
| [https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L274](https://github.com/openclaw/openclaw/blob/main/src/gateway/server-methods/agents.ts#L274) | `ensureAgentWorkspace` is called before append, but its exclusive-create (`wx`) flag silently skips existing symlinks (EEXIST). |
CVSS v4.0 score: 6.9
CVSS v3.1 score: 7.1