-
Notifications
You must be signed in to change notification settings - Fork 0
π‘οΈ Sentinel: [CRITICAL] Fix command injection vulnerability with execSync usage #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||||||||||||||||||||||||
| #!/usr/bin/env node | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const { execSync, spawn, execFileSync } = require('child_process'); | ||||||||||||||||||||||||||||
| const { spawn, execFileSync } = require('child_process'); | ||||||||||||||||||||||||||||
| const path = require('path'); | ||||||||||||||||||||||||||||
| const fs = require('fs'); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -75,7 +75,7 @@ | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| function checkGitRepo() { | ||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||
| execSync('git rev-parse --git-dir', { stdio: 'ignore' }); | ||||||||||||||||||||||||||||
| execFileSync('git', ['rev-parse', '--git-dir'], { stdio: 'ignore' }); | ||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||
| console.error('β Error: Not a git repository'); | ||||||||||||||||||||||||||||
|
|
@@ -110,9 +110,9 @@ | |||||||||||||||||||||||||||
| const url = `http://localhost:${port}`; | ||||||||||||||||||||||||||||
| console.log(`\nπ Opening browser: ${url}`); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const start = (process.platform == 'darwin' ? 'open' : process.platform == 'win32' ? 'start' : 'xdg-open'); | ||||||||||||||||||||||||||||
| const start = (process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'); | ||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||
| execSync(`${start} ${url}`, { stdio: 'ignore' }); | ||||||||||||||||||||||||||||
| execFileSync(start, [url], { stdio: 'ignore' }); | ||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||
|
Comment on lines
+113
to
116
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§© Analysis chainπ Web query:
π‘ Result:
Use one of these patterns: 1)
|
||||||||||||||||||||||||||||
| const start = (process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'); | |
| try { | |
| execSync(`${start} ${url}`, { stdio: 'ignore' }); | |
| execFileSync(start, [url], { stdio: 'ignore' }); | |
| } catch (error) { | |
| try { | |
| if (process.platform === 'win32') { | |
| execFileSync('cmd', ['/c', 'start', '', url], { stdio: 'ignore' }); | |
| } else { | |
| const opener = process.platform === 'darwin' ? 'open' : 'xdg-open'; | |
| execFileSync(opener, [url], { stdio: 'ignore' }); | |
| } | |
| } catch (error) { |
π€ Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@bin/ai-review.js` around lines 113 - 116, The Windows branch currently tries
to call the cmd builtin via execFileSync(start, [url], ...) which always fails;
update the logic around the start variable and the execFileSync invocation in
the block using execFileSync to use the proper Windows invocation
(execFileSync('cmd', ['/c', 'start', '', url], { stdio: 'ignore' })) when
process.platform === 'win32', or alternatively swap to a cross-platform opener
utility; ensure the non-Windows branches still call execFileSync(start, [url], {
stdio: 'ignore' }) and remove the shell-less attempt to run 'start' directly so
the catch block is only hit on real failures.
Check warning on line 209 in bin/ai-review.js
GitHub Actions / test (20.x)
Blocks are nested too deeply (5). Maximum allowed is 4
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,8 @@ function validateFileRequest(file) { | |
|
|
||
| // Additional checks for suspicious patterns | ||
| const suspiciousPatterns = [ | ||
| /\x00/, // Null bytes | ||
| // eslint-disable-next-line no-control-regex | ||
| /\u0000/, // Null bytes | ||
|
Comment on lines
+34
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§© Analysis chainπ Script executed: # First, let's examine the specific lines mentioned in the review
wc -l src/utils/validation.jsRepository: PrakharMNNIT/ai-visual-code-review Length of output: 105 π Script executed: # Read the relevant sections of the file
sed -n '30,50p' src/utils/validation.jsRepository: PrakharMNNIT/ai-visual-code-review Length of output: 828 π Script executed: # Search for Biome configuration files
fd -name "biome.json|biome.jsonc|.biomerc|.biomerc.json"Repository: PrakharMNNIT/ai-visual-code-review Length of output: 308 π Script executed: # Search for ESLint and Biome directives in the file
rg -n "no-control-regex|biome-ignore|u0000" src/utils/validation.jsRepository: PrakharMNNIT/ai-visual-code-review Length of output: 170 π Script executed: # Find biome config files with correct fd syntax
fd "biome" --type fRepository: PrakharMNNIT/ai-visual-code-review Length of output: 88 π Script executed: # Check if biome is in package.json
cat package.json | grep -i biomeRepository: PrakharMNNIT/ai-visual-code-review Length of output: 60 π Script executed: # Look at lines 40-50 to see what's at lines 42-43
sed -n '40,50p' src/utils/validation.jsRepository: PrakharMNNIT/ai-visual-code-review Length of output: 476 π Script executed: # Search for any biome directives in the entire codebase
rg "biome-ignore|@biome" --type jsRepository: PrakharMNNIT/ai-visual-code-review Length of output: 60 π Script executed: # Read the biome.json configuration
cat biome.jsonRepository: PrakharMNNIT/ai-visual-code-review Length of output: 1852 π Script executed: # Get exact line numbers - read full validation.js to count properly
cat -n src/utils/validation.js | sed -n '30,50p'Repository: PrakharMNNIT/ai-visual-code-review Length of output: 975
Lines 35 and 39 use control-character regexes; the ESLint directive on line 34 won't silence Biome's Suggested fix // Additional checks for suspicious patterns
+ const hasNullByte = file.includes('\0');
+ const hasNewlines = /[\r\n]/.test(file);
const suspiciousPatterns = [
- // eslint-disable-next-line no-control-regex
- /\u0000/, // Null bytes
/[<>"|*?]/, // Dangerous file characters
/^\//, // Absolute paths
/^[a-zA-Z]:\\/, // Windows absolute paths
- /[\r\n]/, // Newline injection
];
- if (suspiciousPatterns.some(pattern => pattern.test(file))) {
+ if (hasNullByte || hasNewlines || suspiciousPatterns.some(pattern => pattern.test(file))) {
return { valid: false, error: 'File path contains invalid characters' };
}π§° Toolsπͺ Biome (2.4.4)[error] 35-35: Unexpected control character in a regular expression. (lint/suspicious/noControlCharactersInRegex) π€ Prompt for AI Agents |
||
| /[<>"|*?]/, // Dangerous file characters | ||
| /^\//, // Absolute paths | ||
| /^[a-zA-Z]:\\/, // Windows absolute paths | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update integration test expectation after removing
execSync.This file no longer contains
execSync, but Line 230 inrun-tests.jsstill checksbinContent.includes('execSync'), which will make E1-1 fail after this change set.Suggested fix (outside this file)
π€ Prompt for AI Agents