ruby.lang.security.dangerous-exec.dangerous-exec

profile photo of semgrepsemgrep
Author
6,314
Download Count*

Detected non-static command inside $EXEC. Audit the input to '$EXEC'. If unverified user data can reach this call site, this is a code injection vulnerability. A malicious actor can inject a malicious script to execute arbitrary code.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-exec
    mode: taint
    pattern-sources:
      - patterns:
          - pattern: |
              def $F(...,$ARG,...)
                  ...
              end
          - focus-metavariable: $ARG
      - pattern: params
      - pattern: cookies
    pattern-sinks:
      - patterns:
          - pattern: |
              $EXEC(...)
          - pattern-not: |
              $EXEC("...","...","...",...)
          - pattern-not: |
              $EXEC(["...","...","...",...],...)
          - pattern-not: |
              $EXEC({...},"...","...","...",...)
          - pattern-not: |
              $EXEC({...},["...","...","...",...],...)
          - metavariable-regex:
              metavariable: $EXEC
              regex: ^(system|exec|spawn|Process.exec|Process.spawn|Open3.capture2|Open3.capture2e|Open3.capture3|Open3.popen2|Open3.popen2e|Open3.popen3|IO.popen|Gem::Util.popen|PTY.spawn)$
    message: Detected non-static command inside $EXEC. Audit the input to '$EXEC'.
      If unverified user data can reach this call site, this is a code injection
      vulnerability. A malicious actor can inject a malicious script to execute
      arbitrary code.
    metadata:
      source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_execute.rb
      cwe:
        - "CWE-94: Improper Control of Generation of Code ('Code Injection')"
      owasp:
        - A03:2021 - Injection
      category: security
      technology:
        - ruby
        - rails
      references:
        - https://guides.rubyonrails.org/security.html#command-line-injection
      cwe2022-top25: true
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: HIGH
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    severity: WARNING
    languages:
      - ruby

Examples

dangerous-exec.rb

require 'open3'

def test_params()
  user_input = params['some_key']
# ruleid: dangerous-exec
  exec("ls -lah #{user_input}")

# ruleid: dangerous-exec
  Process.spawn([user_input, "smth"])

# ruleid: dangerous-exec
  output = exec(["sh", "-c", user_input])

# ruleid: dangerous-exec
  pid = spawn(["bash", user_input])

  commands = "ls -lah /raz/dva"
# ok: dangerous-exec
  system(commands)

  cmd_name = "sh"
# ok: dangerous-exec
  Process.exec([cmd_name, "ls", "-la"])
# ok: dangerous-exec
  Open3.capture2({"FOO" => "BAR"}, [cmd_name, "smth"])
# ok: dangerous-exec
  system("ls -lah /tmp")
# ok: dangerous-exec
  exec(["ls", "-lah", "/tmp"])
end

def test_calls(user_input)
  # ruleid: dangerous-exec
    exec("ls -lah #{user_input}")
  
  # ruleid: dangerous-exec
    Process.spawn([user_input, "smth"])
  
  # ruleid: dangerous-exec
    output = exec(["sh", "-c", user_input])
  
  # ruleid: dangerous-exec
    pid = spawn(["bash", user_input])
  
    commands = "ls -lah /raz/dva"
  # ok: dangerous-exec
    system(commands)
  
    cmd_name = "sh"
  # ok: dangerous-exec
    Process.exec([cmd_name, "ls", "-la"])
  # ok: dangerous-exec
    Open3.capture2({"FOO" => "BAR"}, [cmd_name, "smth"])
  # ok: dangerous-exec
    system("ls -lah /tmp")
  # ok: dangerous-exec
    exec(["ls", "-lah", "/tmp"])
  end

  def test_params()
    user_input = params['some_key']
  # ruleid: dangerous-exec
    exec("ls -lah #{user_input}")
  
  # ruleid: dangerous-exec
    Process.spawn([user_input, "smth"])
  
  # ruleid: dangerous-exec
    output = exec(["sh", "-c", user_input])
  
  # ruleid: dangerous-exec
    pid = spawn(["bash", user_input])
  
    commands = "ls -lah /raz/dva"
  # ok: dangerous-exec
    system(commands)
  
    cmd_name = "sh"
  # ok: dangerous-exec
    Process.exec([cmd_name, "ls", "-la"])
  # ok: dangerous-exec
    Open3.capture2({"FOO" => "BAR"}, [cmd_name, "smth"])
  # ok: dangerous-exec
    system("ls -lah /tmp")
  # ok: dangerous-exec
    exec(["ls", "-lah", "/tmp"])
  end
  
  def test_cookies()
    user_input = cookies['some_cookie']
    # ruleid: dangerous-exec
      exec("ls -lah #{user_input}")
    
    # ruleid: dangerous-exec
      Process.spawn([user_input, "smth"])
    
    # ruleid: dangerous-exec
      output = exec(["sh", "-c", user_input])
    
    # ruleid: dangerous-exec
      pid = spawn(["bash", user_input])
    
      commands = "ls -lah /raz/dva"
    # ok: dangerous-exec
      system(commands)
    
      cmd_name = "sh"
    # ok: dangerous-exec
      Process.exec([cmd_name, "ls", "-la"])
    # ok: dangerous-exec
      Open3.capture2({"FOO" => "BAR"}, [cmd_name, "smth"])
    # ok: dangerous-exec
      system("ls -lah /tmp")
    # ok: dangerous-exec
      exec(["ls", "-lah", "/tmp"])
    end