ruby.lang.security.no-send.bad-send

Community Favorite
profile photo of semgrepsemgrep
Author
46,077
Download Count*

Checks for unsafe use of Object#send, try, send, and public_send. These only account for unsafe use of a method, not target. This can lead to arbitrary calling of exit, along with arbitrary code execution. Please be sure to sanitize input in order to avoid this.

Run Locally

Run in CI

Defintion

rules:
  - id: bad-send
    message: Checks for unsafe use of Object#send, try, __send__, and public_send.
      These only account for unsafe use of a method, not target. This can lead
      to arbitrary calling of exit, along with arbitrary code execution. Please
      be sure to sanitize input in order to avoid this.
    metadata:
      cwe:
        - "CWE-94: Improper Control of Generation of Code ('Code Injection')"
      references:
        - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send.rb
        - https://the.igreque.info/posts/2016/01-object-send-considered-harmful-en.html
      category: security
      technology:
        - ruby
      owasp:
        - A03:2021 - Injection
      cwe2022-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    languages:
      - ruby
    severity: ERROR
    pattern-either:
      - pattern: |
          $PARAM = params[...]
          ...
          $RES = $MOD.send($PARAM.$FUNC)
      - pattern: |
          $PARAM = params[...]
          ...
          $RES = $MOD.try($PARAM.$FUNC)
      - pattern: |
          $PARAM = params[...]
          ...
          $RES = $MOD.__send__($PARAM.$FUNC)
      - pattern: |-
          $PARAM = params[...]
          ...
          $RES = $MOD.public_send($PARAM.$FUNC)

Examples

no-send.rb

def bad_send
    # ruleid: bad-send
    method = params[:method]
    @result = User.send(method.to_sym)
end

def ok_send
    method = params[:method] == 1 ? :method_a : :method_b
    @result = User.send(method, *args)
end