Prevention of unauthorized server-side requests to arbitrary domains
import play.api.mvc._
import play.api.libs.ws._
import scala.concurrent.ExecutionContext.Implicits.global
class HomeController @Inject()(ws: WSClient) extends Controller {
def index(url: String) = Action.async { implicit request =>
ws.url(url).get().map { response =>
Ok(response.body)
}
}
}
The
HomeController
class has an
index
method that takes a URL as a parameter. This URL is supplied by the user and the server sends a GET request to this URL using the
ws.url(url).get()
method. The server then returns the response from the requested URL to the user.
This is an example of Server-side Request Forgery (SSRF) because the server is making a request to an arbitrary URL supplied by the user. The user can exploit this by making the server interact with internal resources that are not normally accessible. For example, a user could input a URL that points to an internal service that is only accessible from the server's network, potentially exposing sensitive information or functionality.
import play.api.mvc._
import play.api.libs.ws._
import scala.concurrent.ExecutionContext.Implicits.global
class HomeController @Inject()(ws: WSClient) extends Controller {
private val allowedDomains = List("www.trusteddomain1.com", "www.trusteddomain2.com")
def index(url: String) = Action.async { implicit request =>
val domain = new java.net.URL(url).getHost
if (allowedDomains.contains(domain)) {
ws.url(url).get().map { response =>
Ok(response.body)
}
} else {
Future.successful(BadRequest("Invalid domain"))
}
}
}
The updated code includes a whitelist of allowed domains that the application can make requests to. This is done by creating a list of trusted domains (
allowedDomains
).
When a request is made, the domain of the provided URL is extracted using
new java.net.URL(url).getHost
. This domain is then checked against the
allowedDomains
list. If the domain is in the list, the request is made as before. If the domain is not in the list, a
BadRequest
response is returned, indicating that the provided domain is not allowed.
This approach prevents Server-Side Request Forgery (SSRF) by ensuring that the application can only make requests to trusted domains. It also provides a clear error message when an attempt is made to request a resource from an untrusted domain, which can be useful for logging and detecting malicious activity.
Remember to always keep the
allowedDomains
list updated with the domains that you trust and want your application to interact with.