# REPRO-2026-00094: OpenClaw: Path Traversal in Plugin Installation ## Summary Status: published Severity: critical Type: security Confidence: Unknown ## Identifiers REPRO ID: REPRO-2026-00094 GHSA: GHSA-qrq5-wjgg-rvqw ## Package Name: openclaw Ecosystem: npm Affected: >= 2026.1.20, < 2026.2.1 Fixed: Unknown ## Root Cause # 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` ## Reproduction Details Reproduced: 2026-02-19T19:47:13.372Z Duration: 456 seconds Tool calls: 59 Turns: 38 Handoffs: 2 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00094 pruva-verify GHSA-qrq5-wjgg-rvqw Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00094&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00094/artifacts/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - GitHub Advisory: https://github.com/advisories/GHSA-qrq5-wjgg-rvqw ## Artifacts - repro/reproduction_steps.sh (reproduction_script, 2719 bytes) - repro/rca_report.md (analysis, 4123 bytes) - bundle/ticket.json (other, 8664 bytes) - bundle/ticket.md (ticket, 2990 bytes) - bundle/source.json (other, 5106 bytes) - logs/actual_package_test.log (log, 2719 bytes) - logs/variant_analysis.log (log, 7135 bytes) - logs/reproduction.log (log, 1092 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00094 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00094/artifacts/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00094 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev