javascript.lang.security.audit.code-string-concat.code-string-concat

Author
742
Download Count*
License
Found data from an Express or Next web request flowing to eval
. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid eval
whenever possible.
Run Locally
Run in CI
Defintion
rules:
- id: code-string-concat
message: Found data from an Express or Next web request flowing to `eval`. If
this data is user-controllable this can lead to execution of arbitrary
system commands in the context of your application process. Avoid `eval`
whenever possible.
options:
interfile: true
metadata:
interfile: true
confidence: HIGH
owasp:
- A03:2021 - Injection
cwe:
- "CWE-95: Improper Neutralization of Directives in Dynamically
Evaluated Code ('Eval Injection')"
references:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
- https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback
- https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/
- https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html
category: security
technology:
- node.js
- Express
- Next.js
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
languages:
- javascript
- typescript
severity: ERROR
mode: taint
pattern-sources:
- pattern-either:
- patterns:
- pattern-either:
- pattern-inside: function ... ($REQ, $RES) {...}
- pattern-inside: function ... ($REQ, $RES, $NEXT) {...}
- patterns:
- pattern-either:
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...})
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})
- metavariable-regex:
metavariable: $METHOD
regex: ^(get|post|put|head|delete|options)$
- pattern-either:
- pattern: $REQ.query
- pattern: $REQ.body
- pattern: $REQ.params
- pattern: $REQ.cookies
- pattern: $REQ.headers
- patterns:
- pattern-either:
- pattern-inside: |
import { ...,$IMPORT,... } from 'next/router'
...
- pattern-inside: |
import $IMPORT from 'next/router';
...
- pattern-either:
- patterns:
- pattern-inside: |
$ROUTER = $IMPORT()
...
- pattern-either:
- pattern-inside: |
const { ...,$PROPS,... } = $ROUTER.query
...
- pattern-inside: |
var { ...,$PROPS,... } = $ROUTER.query
...
- pattern-inside: |
let { ...,$PROPS,... } = $ROUTER.query
...
- focus-metavariable: $PROPS
- patterns:
- pattern-inside: |
$ROUTER = $IMPORT()
...
- pattern: |
$ROUTER.query.$VALUE
- patterns:
- pattern: $IMPORT().query.$VALUE
pattern-sinks:
- patterns:
- pattern: |
eval(...)
Examples
code-string-concat.js
function test1(req,res) {
const data = JSON.stringify(req.query.key);
const command = `(secret) => {${data}}`
// ruleid:code-string-concat
return eval(command)
}
test2.post(foo, bar, function (req,res) {
userInput = req.params.input
var command = "new Function('"+userInput+"')";
// ruleid:code-string-concat
return eval(command)
});
function ok1(req,res) {
var command = "eval('123')";
// ok:code-string-concat
return eval(command)
}
Short Link: https://sg.run/96Yk