Skip to content

fix(security): path traversal, SSRF, prompt injection, and 13 CVEs - #15

Merged
ruvnet merged 1 commit into
mainfrom
fix/security-audit-2026-05-23
May 23, 2026
Merged

fix(security): path traversal, SSRF, prompt injection, and 13 CVEs#15
ruvnet merged 1 commit into
mainfrom
fix/security-audit-2026-05-23

Conversation

@ruvnet

@ruvnet ruvnet commented May 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Path traversal in optimizer save()/load() methods: callers could supply ../../etc/passwd as a path. Fixed with a safeResolvePath() helper that strips null bytes and normalises .. components via path.resolve(), and replaces dynamic require('fs') with static imports.
  • SSRF in all three LM providers (OpenAILM, AnthropicLM, OpenRouterLM): the endpoint config option was passed directly to fetch() without validation. A validateEndpoint() guard now enforces HTTPS and blocks private/loopback addresses (RFC-1918, ::1, ULA) at construction time.
  • Prompt injection in ReAct and ChainOfThought: user-supplied string fields were embedded verbatim in LLM prompts via JSON.stringify(input[field]). A new src/utils/sanitize.ts module provides sanitizeUserInput() (null-byte strip, 4096-char cap, pattern-based jailbreak removal) and stripPromptInjection() (20+ patterns covering role overrides, delimiter smuggling, and exfiltration probes). Applied to input fields and tool observations fed back into the ReAct context.
  • 13 npm CVEs — resolved via package.json overrides:
    • protobufjs <=7.5.7 — CRITICAL: 9 CVEs including RCE (GHSA-xq3m-2v4x-88gg, code injection, prototype pollution, multiple DoS). Override to >=7.5.8.
    • tar <=7.5.10 — HIGH: 6 CVEs for path traversal / symlink poisoning during archive extraction. Override to >=7.5.11.
    • qs 6.11.1–6.15.1 — MODERATE: DoS via qs.stringify crash (GHSA-q8mj-m7cp-5q26). Override to >=6.15.0; npm audit fix applied the patch.
    • Result: 0 vulnerabilities (npm audit).

Test plan

  • tsc --noEmit passes with 0 errors (verified in CI and locally)
  • npm test passes 177/177 tests
  • npm audit returns 0 vulnerabilities
  • Manually verify SSRF guard rejects http://localhost/evil and https://192.168.1.1/evil for all three LM providers
  • Verify sanitizeUserInput('ignore all previous instructions') returns '[removed] all previous instructions'
  • Verify save('../../../tmp/evil.json') resolves to an absolute path (no traversal)

Files changed

File Change
src/utils/sanitize.ts New — prompt-injection sanitization helpers
src/utils/index.ts Re-export sanitize helpers
src/lm/providers/openai.ts SSRF guard on endpoint
src/lm/providers/anthropic.ts SSRF guard on endpoint
src/lm/providers/openrouter.ts SSRF guard on endpoint
src/modules/react.ts Sanitize input fields + tool observations
src/modules/chain-of-thought.ts Sanitize input fields
src/optimize/bootstrap.ts Path traversal fix in save/load
src/optimize/miprov2.ts Path traversal fix in save/load
src/optimize/gepa.ts Path traversal fix in save/load
package.json CVE overrides for protobufjs, tar, qs
package-lock.json Regenerated after overrides + audit fix

🤖 Generated with claude-flow

Path traversal
- Replace bare require('fs') + unvalidated paths in BootstrapFewShot,
  MIPROv2, and GEPA save/load with a safeResolvePath() helper that
  strips null bytes and normalises '..' components via path.resolve().
- Add proper 'fs' and 'path' static imports (removes dynamic require calls).

SSRF
- Add validateEndpoint() to OpenAILM, AnthropicLM, and OpenRouterLM that
  enforces HTTPS and rejects private/loopback addresses (localhost, RFC-1918,
  ::1, ULA). Validation runs at construction time before any network call.

Prompt injection
- Add src/utils/sanitize.ts with sanitizeUserInput() and
  stripPromptInjection() helpers that: strip null bytes, cap input at 4096
  chars, and remove 20+ common jailbreak patterns (role overrides, delimiter
  smuggling, exfiltration probes).
- Apply sanitizeUserInput() to user-supplied string fields in ReAct
  (thought-prompt and back-fed tool observations) and ChainOfThought (input
  prompt construction).

Dependency CVEs (npm audit)
- Add package.json overrides for qs (>=6.15.0), protobufjs (>=7.5.8), and
  tar (>=7.5.11) to address GHSA-q8mj-m7cp-5q26 (moderate DoS),
  GHSA-xq3m-2v4x-88gg and 8 related protobufjs RCE/DoS CVEs, and 6
  node-tar path-traversal/symlink-poisoning CVEs.
- Run `npm audit fix` to apply the qs patch; result: 0 vulnerabilities.

TypeScript: tsc --noEmit passes with 0 errors.
Tests: 177/177 passing.

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet
ruvnet merged commit eed2db1 into main May 23, 2026
4 checks passed
@ruvnet
ruvnet deleted the fix/security-audit-2026-05-23 branch May 23, 2026 08:11
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