javascript.lang.security.audit.dangerous-spawn-shell.dangerous-spawn-shell

profile photo of semgrepsemgrep
Author
5,157
Download Count*

Detected non-literal calls to $EXEC(). This could lead to a command injection vulnerability.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-spawn-shell
    message: Detected non-literal calls to $EXEC(). This could lead to a command
      injection vulnerability.
    metadata:
      cwe:
        - "CWE-78: Improper Neutralization of Special Elements used in an OS
          Command ('OS Command Injection')"
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      source-rule-url: https://github.com/nodesecurity/eslint-plugin-security/blob/master/rules/detect-child-process.js
      category: security
      technology:
        - javascript
      references:
        - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#do-not-use-dangerous-functions
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: HIGH
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      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: |
                  require('child_process')
                  ...
              - pattern-inside: |
                  import 'child_process'
                  ...
          - pattern-either:
              - pattern: spawn(...)
              - pattern: spawnSync(...)
              - pattern: $CP.spawn(...)
              - pattern: $CP.spawnSync(...)
          - pattern-either:
              - pattern: |
                  $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",["-c", $ARG, ...],...)
              - patterns:
                  - pattern: $EXEC($CMD,["-c", $ARG, ...],...)
                  - pattern-inside: |
                      $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"
                      ...
              - pattern: |
                  $EXEC("=~/(sh|bash|ksh|csh|tcsh|zsh)/",[$ARG, ...],...)
              - patterns:
                  - pattern: $EXEC($CMD,[$ARG, ...],...)
                  - pattern-inside: |
                      $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"
                      ...
          - focus-metavariable: $ARG

Examples

dangerous-spawn-shell.js

const {spawn, spawnSync} = require('child_process');
const cp = require('child_process');

function test1(userInput) {
    let name = "bash";
    // ruleid: dangerous-spawn-shell
    spawnSync(name, ["-c", userInput]);
}

function test2(userInput) {
    // ruleid: dangerous-spawn-shell
    cp.spawn('sh', [userInput]);
}

function testOk(userInput) {
    foobar(userInput);
    // ok: dangerous-spawn-shell
    spawn('ls', ['-la', '/tmp']);
}