javascript.aws-lambda.security.vm-runincontext-injection.vm-runincontext-injection

profile photo of semgrepsemgrep
Author
unknown
Download Count*

The vm module enables compiling and running code within V8 Virtual Machine contexts. The vm module is not a security mechanism. Do not use it to run untrusted code. If code passed to vm functions is controlled by user input it could result in command injection. Do not let user input in vm functions.

Run Locally

Run in CI

Defintion

rules:
  - id: vm-runincontext-injection
    message: The `vm` module enables compiling and running code within V8 Virtual
      Machine contexts. The `vm` module is not a security mechanism. Do not use
      it to run untrusted code. If code passed to `vm` functions is controlled
      by user input it could result in command injection. Do not let user input
      in `vm` functions.
    metadata:
      owasp:
        - A03:2021 - Injection
      cwe:
        - "CWE-94: Improper Control of Generation of Code ('Code Injection')"
      category: security
      technology:
        - javascript
        - aws-lambda
      cwe2022-top25: true
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      references:
        - https://owasp.org/Top10/A03_2021-Injection
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    languages:
      - javascript
      - typescript
    severity: ERROR
    mode: taint
    pattern-sources:
      - patterns:
          - pattern: $EVENT
          - pattern-either:
              - pattern-inside: |
                  exports.handler = function ($EVENT, ...) {
                    ...
                  }
              - pattern-inside: |
                  function $FUNC ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
              - pattern-inside: |
                  $FUNC = function ($EVENT, ...) {...}
                  ...
                  exports.handler = $FUNC
    pattern-sinks:
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  require('vm');
                  ...
              - pattern-inside: |
                  import 'vm'
                  ...
          - pattern-either:
              - pattern: $VM.runInContext($X,...)
              - pattern: $VM.runInNewContext($X,...)
              - pattern: $VM.runInThisContext($X,...)
              - pattern: $VM.compileFunction($X,...)
              - pattern: new $VM.Script($X,...)
              - pattern: new $VM.SourceTextModule($X,...)
              - pattern: runInContext($X,...)
              - pattern: runInNewContext($X,...)
              - pattern: runInThisContext($X,...)
              - pattern: compileFunction($X,...)
              - pattern: new Script($X,...)
              - pattern: new SourceTextModule($X,...)

Examples

vm-runincontext-injection.js

const vm = require('vm')

exports.handler = async (event) => {
    var input = event['something']
    var sandbox = {
        foo: input
    }
    // ruleid: vm-runincontext-injection
    vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 })


    const code = `
        var x = ${event['something']};
    `
    // ruleid: vm-runincontext-injection
    vm.runInThisContext(code)


    const parsingContext = vm.createContext({name: 'world'})
    const code1 = `return 'hello ' + '${event['something']}'`
    // ruleid: vm-runincontext-injection
    const fn1 = vm.compileFunction(code1, [], { parsingContext })


    const context = vm.createContext({name: event['something']})
    const code2 = `return 'hello ' name`
    // ruleid: vm-runincontext-injection
    const fn2 = vm.compileFunction(code2, [], { parsingContext: context })


    // ruleid: vm-runincontext-injection
    const script = new vm.Script(`
        function add(a, b) {
          return a + ${event['something']};
        }

        const x = add(1, 2);
    `);
    script.runInThisContext();


    // ok: vm-runincontext-injection
    var sandbox2 = {
        foo: 1
    }
    vm.createContext(sandbox2)
    vm.runInContext('safeEval(orderLinesData)', sandbox2, { timeout: 2000 })


    // ok: vm-runincontext-injection
    var sandbox3 = {
        foo: 1
    }
    vm.runInNewContext('safeEval(orderLinesData)', sandbox3, { timeout: 2000 })


    const code2 = `
        var x = 1;
    `
    // ok: vm-runincontext-injection
    vm.runInThisContext(code2)


    const parsingContext = vm.createContext({name: 'world'})
    const code3 = `return 'hello ' + name`
    // ok: vm-runincontext-injection
    const fn3 = vm.compileFunction(code3, [], { parsingContext })


    // ok: vm-runincontext-injection
    const script1 = new vm.Script(`
        function add(a, b) {
          return a + b;
        }

        const x = add(1, 2);
    `);

    script1.runInThisContext();
}