Finding
File: packages/cli/src/update-check.ts:323-328
Severity: CRITICAL
Description
The performAutoUpdate function fetches an install script from a remote URL via curl, then passes the script content directly to bash -c without any validation or integrity checks:
// Line 280-296: Fetch script bytes
const scriptBytes = executor.execFileSync(
"curl",
["--proto", "=https", "-fsSL", installUrl],
{ encoding: "utf8" }
);
const scriptContent = scriptBytes ? scriptBytes.toString() : "";
// Line 323-328: Execute fetched script via bash -c
executor.execFileSync(
"bash",
["-c", scriptContent],
{ stdio: installStdio }
);
Attack Vector:
- If
installUrl (derived from SPAWN_CDN) is compromised or MITM'd despite HTTPS
- If DNS is poisoned to redirect
openrouter.ai or GitHub
- If a CDN cache poisoning attack succeeds
- If the GitHub release artifact is compromised
The attacker can inject arbitrary shell commands that will be executed with the user's permissions during auto-update.
Current Mitigations (insufficient):
curl --proto =https enforces HTTPS (prevents cleartext MITM)
- URL is hardcoded to trusted domains (not user-controllable)
Missing Mitigations:
- No cryptographic signature verification of the downloaded script
- No checksum validation against a known-good hash
- No content inspection before execution
- Script content is trusted blindly once fetched
Recommendation
Option 1: Add Signature Verification (Recommended)
- Sign install scripts with GPG/cosign during release
- Verify signature before execution:
curl -fsSL $URL.sig | gpg --verify - <(echo "$scriptContent")
Option 2: Add Checksum Validation
- Publish SHA256 checksums alongside install scripts
- Verify checksum matches before execution:
const expectedHash = await fetchChecksum();
const actualHash = createHash('sha256').update(scriptContent).digest('hex');
if (actualHash \!== expectedHash) throw new Error('Checksum mismatch');
Option 3: Remove Auto-Update (Least Disruptive)
- Print update notice only (like npm/yarn)
- Let users manually run
spawn update with explicit consent
- Remove
performAutoUpdate entirely
Comparison:
- Option 1 provides strongest security but requires CI/CD changes + GPG key management
- Option 2 provides moderate security with minimal CI changes (publish checksums)
- Option 3 removes the attack surface entirely at the cost of user convenience
Discovered by code-scanner during automated security scan
Finding
File: packages/cli/src/update-check.ts:323-328
Severity: CRITICAL
Description
The
performAutoUpdatefunction fetches an install script from a remote URL viacurl, then passes the script content directly tobash -cwithout any validation or integrity checks:Attack Vector:
installUrl(derived fromSPAWN_CDN) is compromised or MITM'd despite HTTPSopenrouter.aior GitHubThe attacker can inject arbitrary shell commands that will be executed with the user's permissions during auto-update.
Current Mitigations (insufficient):
curl --proto =httpsenforces HTTPS (prevents cleartext MITM)Missing Mitigations:
Recommendation
Option 1: Add Signature Verification (Recommended)
Option 2: Add Checksum Validation
Option 3: Remove Auto-Update (Least Disruptive)
spawn updatewith explicit consentperformAutoUpdateentirelyComparison:
Discovered by code-scanner during automated security scan