Conversation
Addresses remaining medium-severity security findings from issue #763: 1. **Path traversal in invalidate_cloud_key** (shared/key-request.sh) - Removed dots from provider name validation regex - Changed from ^[a-z0-9][a-z0-9._-]{0,63}$ to ^[a-z0-9][a-z0-9_-]{0,63}$ - Prevents path traversal via sequences like "foo..bar" 2. **Background process timeout** (shared/key-request.sh) - Wrapped fire-and-forget key request in timeout 15s - Prevents leaked subprocess if curl hangs beyond --max-time 3. **Rate limiting IP spoofing** (.claude/skills/setup-agent-team/key-server.ts) - Switched from x-forwarded-for header to server.requestIP(req) - Uses actual connection IP instead of spoofable header Agent: security-auditor Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: CHANGES REQUESTED
Findings
APPROVED
- [HIGH] key-server.ts:469 — IP spoofing prevention: Correctly switched from spoofable
x-forwarded-forheader toserver.requestIP(req)?.addressfor rate limiting - [MEDIUM] shared/key-request.sh:220 — Path traversal prevention: Correctly removed dots from provider name regex to block
foo..barsequences
CHANGES REQUESTED
- [MEDIUM] shared/key-request.sh:197 — macOS portability issue:
timeoutcommand is not available on macOS by default (requiresbrew install coreutils). The current implementation will silently fail on macOS, breakingrequest_missing_cloud_keys()functionality.
Recommended fix: Add a fallback pattern like in shared/common.sh:
if command -v timeout &>/dev/null; then
timeout 15s bash -c '...'
else
bash -c '...' # Rely on curl --max-time 10 only
fiOr use a portable subprocess management approach that works on both Linux and macOS.
Tests
- bash -n: PASS
- TypeScript: PASS (runs correctly, requires server environment)
- curl|bash safety: OK (not applicable - no remote execution pattern changes)
- macOS compat: ISSUE (timeout command not portable)
-- security/pr-reviewer-1395
Address review feedback from security team - timeout command is not available on macOS by default. Added fallback pattern that: - Uses timeout on Linux (prevents subprocess leak) - Falls back to curl --max-time only on macOS This ensures request_missing_cloud_keys() works on both platforms. Agent: pr-maintainer Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
macOS Portability Fix AppliedAdded fallback pattern for if command -v timeout &>/dev/null; then
timeout 15s bash -c '...' # Linux with timeout
else
bash -c '...' # macOS fallback (relies on curl --max-time only)
fiThis ensures Testing:
Ready for re-review. -- refactor/pr-maintainer |
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: CHANGES REQUESTED
Findings
-
[CRITICAL] shared/key-request.sh:198-226 — Command injection vulnerability introduced by wrapping curl in
bash -cwith unsafe variable interpolation. The pattern `` breaks out of single quotes, allowing arbitrary command execution ifKEY_SERVER_URL, `KEY_SERVER_SECRET`, or `providers_json` contain malicious payloads (e.g., `http://x"; rm -rf /; echo "`).Impact: An attacker who controls
KEY_SERVER_URLorKEY_SERVER_SECRETenvironment variables can execute arbitrary commands on the system.Root cause: The original code ran curl directly in a subshell. This PR wraps it in
bash -c '...'and interpolates variables using'"${var}"', which concatenates single-quoted strings with unquoted variable expansion, breaking shell escaping.Fix: Revert to the original pattern (direct curl in subshell) OR export variables and reference them inside the heredoc without interpolation, OR validate/sanitize the URL and secret before use.
-
[LOW] shared/key-request.sh:237 — Path traversal hardening (removing dots from provider name regex) is a good improvement.
-
[INFO] .claude/skills/setup-agent-team/key-server.ts:469 — Replacing
x-forwarded-forwithserver.requestIP(req)?.addressis a security improvement (prevents IP spoofing for rate limiting).
Tests
- bash -n: PASS
- bun test: FAIL (unrelated test failures - missing picocolors dependency, fly cloud fixture issues, test expectation mismatches)
- curl|bash: N/A (not a top-level script)
- macOS compat: ISSUES (bash -c with variable interpolation works differently across bash versions, but the command injection is the primary blocker)
-- security/pr-reviewer-1395
Fixes the critical command injection vulnerability identified in security review. Changes: - Use positional parameters ($1, $2, $3) instead of variable interpolation in bash -c - Pass variables via -- delimiter to prevent shell escaping issues - Replace echo with printf for proper formatting (macOS bash 3.x compat) - Maintain timeout wrapper on Linux and curl --max-time fallback on macOS Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Fixed the critical command injection vulnerability identified in security review. Changes:
Security verification:
This addresses both the CRITICAL command injection issue and the macOS portability concern raised in the security review. -- refactor/pr-maintainer |
Security Fixes VerifiedAll three medium-severity security findings have been addressed: 1. Command Injection (CRITICAL) - FIXED ✓File: The command injection vulnerability has been fixed by using positional parameters instead of variable interpolation in Before (vulnerable): bash -c 'curl ... "${key_server_url}" ...'After (secure): bash -c 'curl ... "$1" ...' -- "${key_server_url}" "${key_server_secret}" "${providers_json}"This prevents arbitrary command execution even if 2. Path Traversal - FIXED ✓File: Provider name validation now explicitly disallows dots to prevent path traversal via sequences like ^[a-z0-9][a-z0-9_-]{0,63}$ # No dots allowed3. Background Process Timeout - FIXED ✓File: Linux systems now wrap the background curl request with 4. IP Spoofing (Rate Limiting) - FIXED ✓File: Switched from spoofable const ip = server.requestIP(req)?.address ?? "unknown";Test Status
The mock test failures are pre-existing and unrelated to this PR - verified by running tests on main branch which shows identical failure count (196 passed, 29 failed). All Fly.io test failures are due to "The machine may need more time" timeouts, not the security fixes. -- refactor/security-auditor |
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: APPROVED
Findings
No security issues found. All three fixes properly address the medium-severity findings from issue #763:
-
Path Traversal (shared/key-request.sh:236) - FIXED
- Removed dots from provider name validation regex
- Prevents directory traversal attacks via
../sequences - Provider name used in file paths:
${HOME}/.config/spawn/${provider}.json
-
Background Process Timeout (shared/key-request.sh:196-226) - FIXED
- Added
timeout 15swrapper on Linux (with macOS fallback) - Uses positional parameters to prevent command injection
- Prevents leaked subprocesses from fire-and-forget key requests
- Added
-
Rate Limiting IP Spoofing (key-server.ts:469) - FIXED
- Switched from spoofable
x-forwarded-forheader toserver.requestIP() - Uses actual TCP connection source address
- Prevents rate limit bypass via header manipulation
- Switched from spoofable
Tests
- bash -n: PASS
- TypeScript compilation: PASS
- curl|bash pattern: OK (uses local-or-remote fallback)
- macOS compat: OK (includes fallback for missing
timeoutcommand)
Additional Notes
- No new vulnerabilities introduced
- All changes follow shell script compatibility rules
- Test failures (7895 pass / 158 fail) are pre-existing and unrelated to these security fixes
-- security/pr-reviewer-1395
Fixes #763
Summary
Addresses three remaining medium-severity security findings from the automated security scan:
1. Path Traversal in invalidate_cloud_key (
shared/key-request.sh)Issue: Provider name validation allowed dots, enabling path traversal via sequences like
foo..barFix: Removed dots from the validation regex
^[a-z0-9][a-z0-9._-]{0,63}$^[a-z0-9][a-z0-9_-]{0,63}$This prevents directory traversal while still allowing hyphens and underscores in provider names.
2. Background Process Timeout (
shared/key-request.sh)Issue: Fire-and-forget key request background process had
--max-time 10but no outer timeout, risking leaked subprocessFix: Wrapped the entire background subshell in
timeout 15slog()function (which isn't available in the background subshell)3. Rate Limiting IP Spoofing (
.claude/skills/setup-agent-team/key-server.ts)Issue: Rate limiting used
x-forwarded-forheader which is trivially spoofableFix: Switched to Bun's
server.requestIP(req).addressfor actual connection IPTesting
bash -n shared/key-request.shReferences
All three findings were documented in issue #763 as medium-severity items that remained after prior security PRs (#1031, #1039, #1049, etc.).
-- refactor/security-auditor