javascript.lang.security.detect-child-process.detect-child-process
Community Favorite
semgrep
Author
33,580
Download Count*
License
Detected calls to child_process from a function argument $FUNC
. This could lead to a command injection if the input is user controllable. Try to avoid calls to child_process, and if it is needed ensure user input is correctly sanitized or sandboxed.
Run Locally
Run in CI
Defintion
rules:
- id: detect-child-process
message: "Detected calls to child_process from a function argument `$FUNC`. This
could lead to a command injection if the input is user controllable. Try
to avoid calls to child_process, and if it is needed ensure user input is
correctly sanitized or sandboxed. "
metadata:
cwe:
- "CWE-78: Improper Neutralization of Special Elements used in an OS
Command ('OS Command Injection')"
owasp:
- A01:2017 - Injection
- A03:2021 - Injection
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions
source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js
category: security
technology:
- javascript
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: HIGH
confidence: LOW
vulnerability_class:
- Command Injection
languages:
- javascript
- typescript
severity: ERROR
mode: taint
pattern-sources:
- patterns:
- pattern-inside: |
function ... (...,$FUNC,...) {
...
}
- focus-metavariable: $FUNC
pattern-sinks:
- patterns:
- pattern-either:
- pattern-inside: |
$CP = require('child_process')
...
- pattern-inside: |
import * as $CP from 'child_process'
...
- pattern-inside: |
import $CP from 'child_process'
...
- pattern-either:
- pattern: $CP.exec($CMD,...)
- pattern: $CP.execSync($CMD,...)
- pattern: $CP.spawn($CMD,...)
- pattern: $CP.spawnSync($CMD,...)
- pattern-not-inside: $CP.$EXEC("...",...)
- pattern-not-inside: $CP.$EXEC(["...",...],...)
- pattern-not-inside: |
$CMD = "..."
...
- pattern-not-inside: |
$CMD = ["...",...]
...
- focus-metavariable: $CMD
- patterns:
- pattern-either:
- pattern: child_process.exec($CMD,...)
- pattern: child_process.execSync($CMD,...)
- pattern: child_process.spawn($CMD,...)
- pattern: child_process.spawnSync($CMD,...)
- pattern-not-inside: child_process.$EXEC("...",...)
- pattern-not-inside: child_process.$EXEC(["...",...],...)
- pattern-not-inside: |
$CMD = "..."
...
- pattern-not-inside: |
$CMD = ["...",...]
...
- focus-metavariable: $CMD
Examples
detect-child-process.js
const {exec, spawnSync} = require('child_process');
const cp = require('child_process');
function a(args) {
// ruleid:detect-child-process
exec(`cat *.js ${args[0]}| wc -l`, (error, stdout, stderr) => {
console.log(stdout)
});
}
function a(userInput) {
// ruleid:detect-child-process
cp.spawnSync(userInput);
}
// ok:detect-child-process
exec('ls')
const parentMachine = createMachine({
id: 'parent',
initial: 'waiting',
context: {
localOne: null
},
states: {
waiting: {
entry: assign({
// ok:detect-child-process
localOne: () => spawn(remoteMachine) // <--
}),
on: {
'LOCAL.WAKE': {
actions: send({ type: 'WAKE' }, { to: (context) => context.localOne })
},
'REMOTE.ONLINE': { target: 'connected' }
}
},
connected: {}
}
});
detect-child-process.ts
import { exec } from 'child_process'
import * as cp from 'child_process';
function a(args) {
// ruleid:detect-child-process
exec(`cat *.js ${args[0]}| wc -l`, (error, stdout, stderr) => {
console.log(stdout)
});
}
function a(userInput) {
// ruleid:detect-child-process
cp.spawnSync(userInput);
}
// ok:detect-child-process
exec('ls')
const parentMachine = createMachine({
id: 'parent',
initial: 'waiting',
context: {
localOne: null
},
states: {
waiting: {
entry: assign({
// ok:detect-child-process
localOne: () => spawn(remoteMachine) // <--
}),
on: {
'LOCAL.WAKE': {
actions: send({ type: 'WAKE' }, { to: (context) => context.localOne })
},
'REMOTE.ONLINE': { target: 'connected' }
}
},
connected: {}
}
});
Short Link: https://sg.run/l2lo