scala.lang.security.audit.scalaj-http-ssrf.scalaj-http-ssrf

Author
unknown
Download Count*
License
A parameter being passed directly into Http
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: scalaj-http-ssrf
patterns:
- pattern: Http($URL)
- pattern-inside: |
import scalaj.http.$HTTP
...
- pattern-either:
- pattern-inside: |
def $FUNC(..., $URL: $T, ...) = $A {
...
}
- pattern-inside: |
def $FUNC(..., $URL: $T, ...) = {
...
}
message: A parameter being passed directly into `Http` 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://github.com/scalaj/scalaj-http#simplified-http
category: security
technology:
- scala
- scalaj-http
confidence: LOW
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- scala
severity: WARNING
Examples
scalaj-http-ssrf.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import scalaj.http.{Http, Token}
object Smth {
def call1(url: String): Future[Unit] = {
// ruleid: scalaj-http-ssrf
val response: HttpResponse[String] = Http(url).param("q","monkeys").asString
response.body
}
def call2(): Future[Unit] = {
// ok: scalaj-http-ssrf
val response: HttpResponse[String] = Http("https://www.google.com").param("q","monkeys").asString
response.body
}
}
object FooBar {
def call1(url: String): Future[Unit] = {
// ruleid: scalaj-http-ssrf
val request = Http(url).postForm(Seq("name" -> "jon", "age" -> "29"))
request.asString
}
def call2(): Future[Unit] = {
// ok: scalaj-http-ssrf
val request = Http("https://www.google.com").postForm(Seq("name" -> "jon", "age" -> "29"))
request.asString
}
}
@Singleton
class HomeController @Inject()(
val controllerComponents: ControllerComponents,
implicit val ec: ExecutionContext
) extends BaseController {
def req1(url: String) = Action.async { implicit request: Request[AnyContent] =>
val consumer = Token("key", "secret")
// ruleid: scalaj-http-ssrf
val response = Http(url).postForm(Seq("oauth_callback" -> "oob")).oauth(consumer).asToken
Ok(response.body.key)
}
def req2() = Action.async { implicit request: Request[AnyContent] =>
val consumer = Token("key", "secret")
// ok: scalaj-http-ssrf
val response = Http("https://www.google.com").postForm(Seq("oauth_callback" -> "oob")).oauth(consumer).asToken
Ok(response.body.key)
}
}
Short Link: https://sg.run/OgjB