Summary
skills.install with a download installer fetches a remote archive and extracts it via system tar/unzip without validating entry paths. The same unsafe extraction pattern also appears in the signal-install command when pulling release assets. A malicious archive containing ../ or absolute paths can write files outside the intended target directory (Zip Slip), leading to arbitrary file overwrite and potential code execution on the host.
Executive Risk Snapshot
- CVSS v3.1: 7.6 (High)
- CVSS v4.0: 7.1 (High)
- Primary risk:
skills.install with a download installer fetches a remote archive and extracts it via system tar/unzip without validating entry paths.
Technical Analysis
Describe root cause, what breaks, reproduction details, and fix approach.
Affected Code
File: src/agents/skills-install.ts:202-225 and src/agents/skills-install.ts:291-297
// extractArchive: uses system tar/unzip without validating entry paths
const argv = ["unzip", "-q", archivePath, "-d", targetDir];
return await runCommandWithTimeout(argv, { timeoutMs });
const argv = ["tar", "xf", archivePath, "-C", targetDir];
return await runCommandWithTimeout(argv, { timeoutMs });
// installDownloadSpec: downloads then extracts attacker-controlled archive
const extractResult = await extractArchive({
archivePath,
archiveType,
targetDir,
stripComponents: spec.stripComponents,
timeoutMs,
});
File: src/commands/signal-install.ts:150-166
await downloadToFile(assetUrl, archivePath);
if (assetName.endsWith(".zip")) {
await runCommandWithTimeout(["unzip", "-q", archivePath, "-d", installRoot], {
timeoutMs: 60_000,
});
} else if (assetName.endsWith(".tar.gz") || assetName.endsWith(".tgz")) {
await runCommandWithTimeout(["tar", "-xzf", archivePath, "-C", installRoot], {
timeoutMs: 60_000,
});
}
Steps to Reproduce
- Create a zip or tar archive containing a file with a path like
../../.ssh/authorized_keys or ../config/openclaw.json.
- Publish it at a URL and reference it in a skill
download install spec.
- Run
skills.install for that skill; the archive is extracted and writes outside targetDir.
Recommended Fix
Avoid system tar/unzip for untrusted archives. Use a safe extraction routine that rejects entries whose resolved paths escape targetDir (similar to infra/archive.ts zip handling), or enforce strict path validation before extraction. For tar, use the node tar library with a filter that validates each entry path against targetDir. Apply the same safe extraction logic to the signal-install extraction path as well.
Detailed Risk Analysis
CVSS Assessment
| Metric |
Value |
| Score |
7.6 / 10.0 |
| Severity |
High |
| Vector |
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:H/A:H |
CVSS v3.1 Calculator
Attack Surface
How is this reached?
Authentication required?
Entry point: skills.install with a download installer spec (remote URL) and signal-install command fetching a remote release asset
Exploit Conditions
Complexity: [x] Low / [ ] High
User interaction: [ ] None / [x] Required
Prerequisites: Ability to trigger skill installation (or convince an operator to install a skill) with a malicious download URL, or to supply a malicious release asset to the signal installer.
Impact Assessment
Scope: [x] Unchanged / [ ] Changed
| Impact Type |
Level |
Description |
| Confidentiality |
Low |
Overwritten files can expose secrets indirectly (e.g., rewriting configs to enable exfil). |
| Integrity |
High |
Arbitrary file overwrite outside the target dir (e.g., shell profiles, config files, scripts). |
| Availability |
High |
Overwriting critical files can break the service or host environment. |
References
Summary
skills.installwith adownloadinstaller fetches a remote archive and extracts it via systemtar/unzipwithout validating entry paths. The same unsafe extraction pattern also appears in thesignal-installcommand when pulling release assets. A malicious archive containing../or absolute paths can write files outside the intended target directory (Zip Slip), leading to arbitrary file overwrite and potential code execution on the host.Executive Risk Snapshot
skills.installwith adownloadinstaller fetches a remote archive and extracts it via systemtar/unzipwithout validating entry paths.Technical Analysis
Describe root cause, what breaks, reproduction details, and fix approach.
Affected Code
File:
src/agents/skills-install.ts:202-225andsrc/agents/skills-install.ts:291-297File:
src/commands/signal-install.ts:150-166Steps to Reproduce
../../.ssh/authorized_keysor../config/openclaw.json.downloadinstall spec.skills.installfor that skill; the archive is extracted and writes outsidetargetDir.Recommended Fix
Avoid system
tar/unzipfor untrusted archives. Use a safe extraction routine that rejects entries whose resolved paths escapetargetDir(similar toinfra/archive.tszip handling), or enforce strict path validation before extraction. For tar, use the nodetarlibrary with afilterthat validates each entry path againsttargetDir. Apply the same safe extraction logic to thesignal-installextraction path as well.Detailed Risk Analysis
CVSS Assessment
Attack Surface
How is this reached?
Authentication required?
Entry point:
skills.installwith adownloadinstaller spec (remote URL) andsignal-installcommand fetching a remote release assetExploit Conditions
Complexity: [x] Low / [ ] High
User interaction: [ ] None / [x] Required
Prerequisites: Ability to trigger skill installation (or convince an operator to install a skill) with a malicious download URL, or to supply a malicious release asset to the signal installer.
Impact Assessment
Scope: [x] Unchanged / [ ] Changed
References