scala.lang.security.audit.dangerous-shell-run.dangerous-shell-run

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Found dynamic content used for the external process. This is dangerous if arbitrary data can reach this function call because it allows a malicious actor to execute commands. Ensure your variables are not controlled by users or sufficiently sanitized.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-shell-run
    patterns:
      - pattern: Seq($SH, "-c", $CMD, ...)
      - pattern-not: Seq($SH, "-c", "...", ...)
      - pattern-inside: |
          import sys.process
          ...
      - pattern-not-inside: |
          $CMD = "..."
          ...
      - pattern-either:
          - pattern-inside: Seq(...).!
          - pattern-inside: Seq(...).!!
          - pattern-inside: Seq(...).lazyLines
      - metavariable-regex:
          metavariable: $SH
          regex: '"(sh|bash|ksh|csh|tcsh|zsh)"'
    message: Found dynamic content used for the external process. This is dangerous
      if arbitrary data can reach this function call because it allows a
      malicious actor to execute commands. Ensure your variables are not
      controlled by users or sufficiently sanitized.
    languages:
      - scala
    severity: ERROR
    metadata:
      category: security
      cwe:
        - "CWE-78: Improper Neutralization of Special Elements used in an OS
          Command ('OS Command Injection')"
      owasp:
        - A01:2017 - Injection
        - A03:2021 - Injection
      technology:
        - scala
      confidence: LOW
      references:
        - https://owasp.org/Top10/A03_2021-Injection
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Command Injection

Examples

dangerous-shell-run.scala

class Foo {
  def run1(message: String) = {
    import sys.process._
    // ruleid: dangerous-shell-run
    Seq("sh", "-c", message).!
  }

  def run2(message: String) = {
    import sys.process._
    // ruleid: dangerous-shell-run
    val result = Seq("bash", "-c", message).!!
    return result
  }

  def run3(message: String) = {
    import sys.process._
    // ok: dangerous-shell-run
    Seq("ls", "-la").!!
  }

  def run4(message: String) = {
    import sys.process._
    // ok: dangerous-shell-run
    Seq("sh", "-c", "ls").!!
  }

  def run5(message: String) = {
    import sys.process._
    // ok: dangerous-shell-run
    Seq("sh", "-c", message)
  }

  def run6(message: String) = {
    // ok: dangerous-shell-run
    val result = Seq("bash", "-c", message).!!
    return result
  }
}