contrib.nodejsscan.eval_vm_injection.vm_compilefunction_injection

Author
99
Download Count*
License
Untrusted user input in vm.compileFunction()
can result in code injection.
Run Locally
Run in CI
Defintion
rules:
- id: vm_compilefunction_injection
patterns:
- pattern-inside: |
require('vm');
...
- pattern-either:
- pattern-inside: function ($REQ, $RES, ...) {...}
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: >
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <...
$REQ.$QUERY.$FOO ...>},...);
- pattern: >
$CONTEXT = <... $REQ.$QUERY.$FOO ...>; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$CONTEXT = <... {$NAME:$REQ.$QUERY.$FOO} ...>; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>}; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$VAR = <... $REQ.$QUERY.$FOO ...>; ... $CONTEXT = {$NAME: <...
$VAR ...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext:
<... $CONTEXT ...>},...);
- pattern: |
$OPTS = {parsingContext: <... $REQ.$QUERY.$FOO ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$CONTEXT = <... $REQ.$QUERY.$FOO ...>;
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$CONTEXT = {$NAME: <... $REQ.$QUERY.$FOO ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$VAR = <... $REQ.$QUERY.$FOO ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: >
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $REQ.$BODY
...>},...);
- pattern: >
$CONTEXT = <... $REQ.$BODY ...>; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$CONTEXT = <... {$NAME:$REQ.$BODY} ...>; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$CONTEXT = {$NAME: <... $REQ.$BODY ...>}; ...
$VM.compileFunction($CODE,$PARAMS,{parsingContext: <... $CONTEXT
...>},...);
- pattern: >
$VAR = <... $REQ.$BODY ...>; ... $CONTEXT = {$NAME: <... $VAR
...>}; ... $VM.compileFunction($CODE,$PARAMS,{parsingContext: <...
$CONTEXT ...>},...);
- pattern: |
$OPTS = {parsingContext: <... $REQ.$BODY ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$CONTEXT = <... $REQ.$BODY ...>;
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$CONTEXT = {$NAME: <... $REQ.$BODY ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
- pattern: |
$VAR = <... $REQ.$BODY ...>;
...
$CONTEXT = {$NAME: <... $VAR ...>};
...
$OPTS = {parsingContext: <... $CONTEXT ...>};
...
$VM.compileFunction($CODE,$PARAMS,$OPTS,...);
message: Untrusted user input in `vm.compileFunction()` can result in code
injection.
severity: ERROR
languages:
- javascript
metadata:
owasp: A01:2017 - Injection
cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')"
category: security
technology:
- node.js
- express
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
Examples
eval_vm_injection.js
const vm = require('vm')
let ctrl1 = function test1(req, res) {
// ruleid:vm_runincontext_injection
var input = req.query.something || ''
var sandbox = {
foo: input
}
vm.createContext(sandbox)
vm.runInContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 })
res.send('hello world')
}
app.get('/', ctrl1)
app.get('/', (req, res) => {
// ruleid:vm_runincontext_injection
var sandbox = {
foo: req.query.userInput
}
vm.createContext(sandbox)
vm.runInContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 })
res.send('hello world')
})
var ctrl2 = null;
ctrl2 = function test2(req, res) {
// ruleid:vm_runinnewcontext_injection
var input = req.query.something || ''
var sandbox = {
foo: input
}
vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 })
res.send('hello world')
}
app.get('/', ctrl2)
app.get('/', function (req, res) {
// ruleid:vm_runinnewcontext_injection
var sandbox = {
foo: req.query.userInput
}
vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 })
res.send('hello world')
})
app.get('/', function (req, res) {
// ruleid:vm_code_injection
const code = `
var x = ${req.query.userInput};
`
vm.runInThisContext(code)
res.send('hello world')
})
app.get('/', function test4(req, res) {
const parsingContext = vm.createContext({ name: 'world' })
// ruleid:vm_code_injection
const code = `return 'hello ' + ${req.query.userInput}`
let fn = vm.compileFunction(code, [], { parsingContext })
res.send('hello world')
})
app.get('/', (req, res) => {
// ruleid:vm_compilefunction_injection
const context = vm.createContext({ name: req.query.userInput })
let code = `return 'hello ' name`
const fn = vm.compileFunction(code, [], { parsingContext: context })
res.send('hello world')
})
app.get('/', function (req, res) {
// ruleid:vm_code_injection
const script = new vm.Script(`
function add(a, b) {
return a + ${req.query.userInput};
}
const x = add(1, 2);
`);
script.runInThisContext();
res.send('hello world')
})
Short Link: https://sg.run/Bkg6