scala.lang.security.audit.io-source-ssrf.io-source-ssrf

profile photo of semgrepsemgrep
Author
unknown
Download Count*

A parameter being passed directly into fromURL most likely lead to SSRF. This could allow an attacker to send data to their own server, potentially exposing sensitive data sent with this request. They could also probe internal servers or other resources that the server runnig this code can access. Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode the correct host.

Run Locally

Run in CI

Defintion

rules:
  - id: io-source-ssrf
    patterns:
      - pattern-either:
          - pattern: Source.fromURL($URL,...)
          - pattern: Source.fromURI($URL,...)
      - pattern-inside: |
          import scala.io.$SOURCE
          ...
      - pattern-either:
          - pattern-inside: |
              def $FUNC(..., $URL: $T, ...) = $A {
                ...
              }
          - pattern-inside: |
              def $FUNC(..., $URL: $T, ...) = {
                ...
              }
    message: A parameter being passed directly into `fromURL` most likely lead to
      SSRF. This could allow an attacker to send data to their own server,
      potentially exposing sensitive data sent with this request. They could
      also probe internal servers or other resources that the server runnig this
      code can access. Do not allow arbitrary hosts. Instead, create an
      allowlist for approved hosts hardcode the correct host.
    metadata:
      cwe:
        - "CWE-918: Server-Side Request Forgery (SSRF)"
      owasp:
        - A10:2021 - Server-Side Request Forgery (SSRF)
      references:
        - https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
        - https://www.scala-lang.org/api/current/scala/io/Source$.html#fromURL(url:java.net.URL)(implicitcodec:scala.io.Codec):scala.io.BufferedSource
      category: security
      technology:
        - scala
      confidence: MEDIUM
      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:
        - Server-Side Request Forgery (SSRF)
    languages:
      - scala
    severity: WARNING

Examples

io-source-ssrf.scala

package controllers

import javax.inject._
import play.api._
import play.api.mvc._
import scala.io.{Codec, Source}

object Smth {
  def call1(request_url: String) = {
    // ruleid: io-source-ssrf
    val html = Source.fromURI(request_url)
    val data = html.mkString
    data
  }

  def call2() = {
    // ok: io-source-ssrf
    val html = Source.fromURI("https://www.google.com")
    val data = html.mkString
    data
  }
}

object FooBar {
  def call1(request_url: String, codec: Codec) = {
    // ruleid: io-source-ssrf
    val res = Source.fromURL(request_url)(codec).mkString
    res
  }

  def call2() = {
    // ok: io-source-ssrf
    val res = Source.fromURL("https://www.google.com")(codec).mkString
    res
  }
}

@Singleton
class HomeController @Inject()(
  val controllerComponents: ControllerComponents,
  implicit val ec: ExecutionContext
) extends BaseController {

  def req1(request_url: String) = Action.async { implicit request: Request[AnyContent] =>
    val codec = whatIsCodec()
    // ruleid: io-source-ssrf
    val res = Source.fromURL(request_url, codec).mkString
    Ok(res)
  }

  def req2() = Action.async { implicit request: Request[AnyContent] =>
    // ok: io-source-ssrf
    val res = Source.fromURL("https://www.google.com").mkString
    Ok(res)
  }

}