Skip to content

fix: address critical security vulnerabilities (path traversal, command injection, and more)#60

Open
19prince wants to merge 1 commit intogemini-cli-extensions:mainfrom
19prince:security/fix-critical-vulnerabilities
Open

fix: address critical security vulnerabilities (path traversal, command injection, and more)#60
19prince wants to merge 1 commit intogemini-cli-extensions:mainfrom
19prince:security/fix-critical-vulnerabilities

Conversation

@19prince
Copy link
Copy Markdown

Summary

Security audit of the MCP server identified several vulnerabilities. This PR fixes all of them.

Critical / High

  • Path traversal → arbitrary file read (fileHandler.ts): findInputFile() previously accepted absolute paths (e.g. /etc/passwd, ~/.ssh/id_rsa) and returned them verbatim for fs.readFile(), which then sent the contents to the Gemini API. Fix: reject absolute paths outright, reject .. sequences, resolve the final path and assert it stays inside the intended search root.

  • Command injection (imageGenerator.ts): openImagePreview() built shell commands via string interpolation — open "${filePath}" — and passed them to exec(). A path containing " or backticks could break out of the quoting. Fix: replaced with execFile() + argument array, removing shell involvement entirely.

Medium

  • No runtime input validation (index.ts): all tool arguments were accepted via bare TypeScript casts with no runtime enforcement. Added validateToolArgs() enforcing: non-empty prompt, 10 000 character limit, outputCount integer 1–8, steps integer 2–8, non-empty file with 255 char limit.

Low

  • Error messages leaking filesystem layout (imageGenerator.ts): "file not found" responses previously included the full list of searched paths (disclosing process.cwd(), $HOME, etc.). Replaced with a generic message.

  • Unvalidated NANOBANANA_MODEL env var (imageGenerator.ts): model name now checked against an allowlist of the three documented models; unknown values fall back to the default with a warning.

  • Unbounded file write (fileHandler.ts): saveImageFromBase64() now rejects API responses larger than 50 MB before writing to disk.

  • Vulnerable dependencies: npm audit fix resolves 5 CVEs — ReDoS in @modelcontextprotocol/sdk, ajv, qs; DoS in body-parser; HMAC bypass in jws.

Test plan

  • npm run build passes cleanly in mcp-server/
  • npm audit reports 0 vulnerabilities
  • edit_image with an absolute path (e.g. /etc/passwd) returns "File not found" rather than reading the file
  • edit_image with a ../ traversal path returns "File not found"
  • generate_image with an empty prompt returns a validation error
  • generate_image with outputCount: 99 returns a validation error
  • Image preview opens correctly on macOS/Linux (execFile path)

🤖 Generated with Claude Code

- Path traversal (High): findInputFile() now rejects absolute paths and
  path traversal sequences (../), resolves paths and verifies they stay
  within the intended search root before any fs.readFile call

- Command injection (High): openImagePreview() replaced exec() string
  interpolation with execFile() + argument array, removing shell
  involvement entirely

- Input validation (Medium): added validateToolArgs() in index.ts
  enforcing non-empty prompt, 10k char limit, integer ranges for
  outputCount/steps (1-8/2-8), non-empty file param

- Error message leakage (Low): replaced full filesystem search path
  disclosure with a generic not-found message

- Model name allowlist (Low): NANOBANANA_MODEL validated against known
  model identifiers; falls back to default with warning if unknown

- File size guard (Low): saveImageFromBase64() rejects API responses
  larger than 50 MB before writing to disk

- Vulnerable dependencies: npm audit fix resolves 5 CVEs including
  ReDoS in @modelcontextprotocol/sdk, ajv, qs; DoS in body-parser;
  HMAC bypass in jws

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@google-cla
Copy link
Copy Markdown

google-cla bot commented Mar 18, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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