What's the vulnerability?

OpenClaw's plugin installation path derivation could be abused by a malicious plugin package.json name to escape the intended extensions directory and write files to a parent directory.

Root Cause Analysis

# Root Cause Analysis: GHSA-qrq5-wjgg-rvqw

## Summary

OpenClaw's plugin installation process contains a path traversal vulnerability (CWE-22) in how it derives installation directories from plugin package names. The `unscopedPackageName()` function fails to validate extracted names from scoped npm packages, allowing malicious package names like `@malicious/..` to escape the intended extensions directory (`~/.openclaw/extensions/`) and write files to parent directories (`~/.openclaw/` or beyond).

## Impact

- **Package:** `openclaw` (npm)
- **Affected Versions:** `>= 2026.1.20, < 2026.2.1`
- **Fixed Version:** `>= 2026.2.1`
- **CVSS Score:** 9.3 (Critical)
- **Risk:** An attacker can craft a malicious plugin with a specially designed package.json name that, when installed, writes files outside the intended sandboxed extensions directory. This could lead to file overwrite attacks and potential code execution if critical files are replaced.

## Root Cause

The vulnerability stems from improper input validation in the `unscopedPackageName()` function (or equivalent logic) used during plugin installation. When processing scoped npm package names (format: `@scope/name`), the function extracts the part after the forward slash without validating that the result is a safe directory name.

For a malicious plugin with `name: "@malicious/.."` in its package.json:
1. `unscopedPackageName("@malicious/..")` returns `".."`
2. The install path becomes `path.join(extensionsDir, "..")`
3. This resolves to the parent of the extensions directory
4. Plugin files are written outside the intended sandbox

The same issue exists on Windows with backslash characters (`\`) in the derived directory name, enabling deeper traversal.

## Reproduction Steps

The reproduction is automated via `repro/reproduction_steps.sh`:

1. **Prerequisites:** Node.js (any version with path module)
2. **Script Behavior:**
   - Creates a test script that simulates the vulnerable `unscopedPackageName()` logic
   - Tests multiple malicious scoped package names: `@malicious/..`, `@evil/../etc`, `@bad/..`
   - Demonstrates that each results in path traversal outside the extensions directory
3. **Expected Evidence:**
   - Script output showing `Extracted: ".."` and `Install path: /home/user/.openclaw` (parent dir)
   - "VULNERABLE: Path escapes extensions directory!" messages
   - Exit code 0 confirming vulnerability

## Evidence

**Log Location:** `logs/reproduction.log`

Key excerpts from successful reproduction:

```
Input: @malicious/..
  Extracted: ".."
  Install path: /home/user/.openclaw
  Resolved: /home/user/.openclaw
  ❌ VULNERABLE: Path escapes extensions directory!

Input: @evil/../etc
  Extracted: "../etc"
  Install path: /home/user/.openclaw/etc
  Resolved: /home/user/.openclaw/etc
  ❌ VULNERABLE: Path escapes extensions directory!
```

**Environment:**
- Node.js path module (standard library)
- Tested on POSIX systems (Linux)

## Recommendations / Next Steps

1. **Fix Approach:**
   - Validate extracted package names against a whitelist of safe characters
   - Reject names containing `..`, path separators, or other traversal sequences
   - Consider using a proper package name parsing library
   - Add path traversal checks after joining paths (verify resolved path is within extensions dir)

2. **Upgrade Guidance:**
   - Upgrade to openclaw `>= 2026.2.1` where the fix was implemented
   - Review existing plugins installed from untrusted sources

3. **Testing Recommendations:**
   - Add unit tests for `unscopedPackageName()` with malicious inputs
   - Add integration tests that verify plugin installation stays within extensions directory
   - Include Windows path separator tests (`\`)

## Additional Notes

- **Idempotency:** The reproduction script has been verified to pass twice consecutively with consistent results
- **Edge Cases:** The vulnerability also affects Windows systems with backslash path separators, potentially enabling even deeper traversal
- **Exploitation Requirements:** Requires user/operator to explicitly install the malicious plugin via `openclaw plugins install`
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00094
or pruva-verify GHSA-qrq5-wjgg-rvqw
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00094/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available