Skip to content

fix: patch command injection, OAuth CSRF, and path deny-list bypass#23

Open
olleepalmer wants to merge 2 commits intosuitedaces:mainfrom
olleepalmer:fix/security-vulnerabilities
Open

fix: patch command injection, OAuth CSRF, and path deny-list bypass#23
olleepalmer wants to merge 2 commits intosuitedaces:mainfrom
olleepalmer:fix/security-vulnerabilities

Conversation

@olleepalmer
Copy link
Copy Markdown

Summary

Security fixes for 4 vulnerabilities identified during a code audit:

  • [Critical] Command injection in macNotify() (src/gateway/server.ts) — execSync with string interpolation allows arbitrary command execution via crafted notification title/body. Replaced with execFileSync using argument arrays to avoid shell interpretation.
  • [Critical] Command injection in checkBinaryExists() (src/skills/loader.ts) — execSync(which ${bin}) passes skill YAML metadata directly into shell. A malicious community skill could execute arbitrary commands at load time. Replaced with execFileSync('which', [bin]).
  • [High] OAuth state mismatch ignored (src/providers/claude.ts) — PKCE state param mismatch was logged as a warning but token exchange proceeded anyway, defeating CSRF protection. Now rejects the exchange with an error.
  • [Low] ALWAYS_DENIED paths overridable (src/config.ts) — Custom deniedPaths in gateway config replaced the built-in deny list (~/.ssh, ~/.aws, ~/.gnupg, etc.) instead of merging with it. Now always merges so sensitive dirs stay protected.

Test plan

  • Verify notifications still work on macOS (macNotify with normal strings)
  • Verify skill loading still detects installed binaries
  • Verify OAuth login flow succeeds with matching state
  • Verify OAuth login flow rejects mismatched state
  • Verify custom deniedPaths config still blocks specified paths
  • Verify ~/.ssh, ~/.aws, ~/.gnupg are denied even with custom deniedPaths

🤖 Generated with Claude Code

- Replace execSync shell interpolation with execFileSync in macNotify()
  and checkBinaryExists() to prevent OS command injection (CWE-78)
- Reject OAuth state mismatch instead of ignoring it to prevent CSRF
- Merge ALWAYS_DENIED with user deniedPaths instead of replacing, so
  ~/.ssh, ~/.aws, ~/.gnupg are always protected

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 25, 2026

@olleepalmer is attempting to deploy a commit to the DevApe Team on Vercel.

A member of the Team first needs to authorize it.

- Replace naive startsWith() path matching with segment-aware boundary
  checks so /safe no longer matches /safe_evil (CWE-22)
- Resolve parent directory via realpathSync for non-existent targets to
  prevent symlink-parent bypasses on file creation (CWE-367)
- Enforce sender allowlist on Telegram callback queries (approve/deny
  buttons, question responses) to prevent unauthorized users from
  approving tool executions (CWE-284)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant