Scope child_process_exec to JS/TS files (fix Python false-positive)#57888
Open
emora-hash wants to merge 1 commit into
Open
Scope child_process_exec to JS/TS files (fix Python false-positive)#57888emora-hash wants to merge 1 commit into
emora-hash wants to merge 1 commit into
Conversation
Adds optional file_extensions filter to SECURITY_PATTERNS. Scopes the child_process_exec rule to .js/.ts/.tsx/.jsx/.cjs/.mjs so it no longer false-positives on Python's asyncio.create_subprocess_exec(. Other rules keep universal behavior (no file_extensions field set). Backward-compatible.
This was referenced May 11, 2026
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.
Scope
child_process_execto JS/TS files (fix Python false-positive)Summary
The
child_process_execrule insecurity_reminder_hook.pyuses the substring"exec("to matchchild_process.exec()invocations. This substring also matches Python'sasyncio.create_subprocess_exec(, which is the safe Python variant (usesposix_spawn, no shell, no command-injection risk).The hook fires on first Write of any Python file containing
create_subprocess_exec(and emits a JavaScript-flavored warning recommendingexecFileNoThrow.ts— confusing in a Python context and pure noise.This PR adds an optional
file_extensionsfield toSECURITY_PATTERNSentries and applies it tochild_process_execso the rule only fires on JS/TS files wherechild_process.exec()is actually a concept.Repro (before fix)
First Write triggers the
child_process_execwarning. Second Write is suppressed (per-session state). Cosmetic friction + misleading recommendation.Change
file_extensions: list[str](lowercase extensions including leading dot)._path_extension(normalized_path)returns the lowercase extension or empty string.check_patterns()skips a substring rule when itsfile_extensionsis set and the current file's extension isn't included.file_extensionskeep the legacy behavior (apply to all files) — fully backward-compatible.child_process_execonly in this PR:[".js", ".ts", ".tsx", ".jsx", ".cjs", ".mjs"].Other potentially language-specific rules (
new_function_injection,react_dangerously_set_html,document_write_xss,innerHTML_xss,pickle_deserialization) are intentionally untouched in this PR to keep scope minimal. Follow-up PRs can scope each individually after this mechanism lands.eval_injectionis deliberately left universal — theevalbuiltin is dangerous in JS, Python, Ruby, and beyond.Test
Included
test_fix.py(smoke test, not part of the PR — just included here for the reviewer's confidence). 3 cases:asyncio.create_subprocess_exec(child_process.exec(child_process_execeval(eval_injection(universal)All 3 pass.
Files changed
plugins/security-guidance/hooks/security_reminder_hook.py(+20 / -0)Notes for reviewer
_path_extension()deliberately handles the "no extension" and "dot-in-dirname-only" cases (e.g.,/path/with.dot/no-extensionreturns"")..lower()so extensions in YAML/manifest comparison and case-mismatch in user paths both work.file_extensionskeeps universal matching.