fix: harden shell escaping, predicate interpolation, and version codegen against injection#289
Open
sebastiondev wants to merge 1 commit intogetsentry:mainfrom
Open
Conversation
… and sanitize predicate/version inputs - command.ts: Replace hand-rolled double-quote regex escaping with the existing shellEscapeArg() helper that uses POSIX single-quote wrapping. The previous regex missed $(), backticks, and newlines inside double quotes, allowing command injection when useShell=true. - log_capture.ts: Add escapePredicateString() to sanitize bundleId and custom subsystem values before interpolating them into NSPredicate strings, preventing predicate injection via crafted double-quotes or backslashes. - generate-version.ts: Validate version fields against a version pattern and use JSON.stringify() instead of raw string interpolation to prevent code injection via a compromised package.json.
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| macOSTemplateVersion: string; | ||
| } | ||
|
|
||
| const VERSION_REGEX = /^v?[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$/; |
Contributor
There was a problem hiding this comment.
Version regex rejects valid semver pre-release hyphens
Medium Severity
VERSION_REGEX uses [a-zA-Z0-9.] for pre-release and build-metadata character classes, which doesn't include -. The semver spec explicitly allows hyphens in these identifiers (e.g., 2.4.0-beta-1, 1.0.0-rc-1, 1.0.0+build-42). The validateVersion function will throw on valid semver versions containing hyphens in pre-release or build metadata, blocking releases that use common naming conventions like beta-1 or rc-2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
This PR addresses three injection vectors found during a security review of command execution and string interpolation patterns.
1. Command injection via double-quote shell escaping (CWE-78, Medium)
File:
src/utils/command.tsWhen
useShell=true, arguments were escaped by wrapping in double quotes with only"and\escaped. This is insufficient because$(), backticks, and other shell expansions are still interpreted inside double quotes in/bin/sh -c.For example, an argument like
com.example$(id)appwould pass the regex check, get wrapped as"com.example$(id)app", and the$(id)subshell would execute.Fix: Replace the hand-rolled double-quote regex escaping with the projects own
shellEscapeArg()fromshell-escape.ts, which uses POSIX single-quote wrapping ('technique). Single-quoted strings in POSIX shell have no interpolation — this is the standard safe approach.Callers affected:
platform-detection.tsandaxe-helpers.tspassuseShell=truewith potentially user-influenced arguments (scheme names, project paths from MCP tool calls).2. Predicate injection via unsanitized bundleId (CWE-78, Low-Medium)
File:
src/utils/log_capture.tsThe
bundleIdparameter was interpolated directly into an NSPredicate string (subsystem == "${bundleId}"). A bundleId containing"could break out of the predicate string context. While the predicate is passed as an argument tospawn()(not through shell), thelogcommands predicate parser interprets the string, so malformed predicates could alter filtering behavior or cause errors.Fix: Add
escapePredicateString()that backslash-escapes\and"before interpolation. Applied to all predicate construction paths including custom subsystem arrays.3. Code injection via version string interpolation (CWE-94, Low)
File:
scripts/generate-version.tsVersion fields from
package.jsonwere interpolated directly into generated TypeScript source using template literals (export const version = '${pkg.version}';). A tamperedpackage.json(e.g., supply chain attack) could inject arbitrary code.Fix: Use
JSON.stringify()for safe string literal embedding, and validate all version fields against a version pattern before interpolation.Testing
src/version.tsbuild artifact)log_capture.test.ts,platform-detection.test.ts,launch_app_sim.test.ts,launch_app_logs_sim.test.ts, and all logging/macOS tool tests