Prevention of HTTP parameter pollution
import play.api.mvc._
def vulnerableAction = Action { request =>
val parameter = request.getQueryString("param")
parameter match {
case Some(x) => Ok("Received parameter: " + x)
case None => BadRequest("Missing parameter")
}
}
The above Scala code is a simple Play Framework action that fetches a query string parameter named "param" from the HTTP request. The
getQueryString
method is used to retrieve the parameter value.
The vulnerability lies in the fact that the
getQueryString
method will only return the first occurrence of the parameter in the query string, ignoring any subsequent occurrences. This means that if an attacker injects extra "param" parameters into the HTTP request, these extra parameters will be ignored by the server, potentially causing unexpected behavior.
For instance, if an attacker sends a request like
http://example.com/vulnerableAction?param=legitimate¶m=malicious
, the server will only see the "legitimate" value and will completely ignore the "malicious" value. This is a classic example of HTTP Parameter Pollution (HPP).
An attacker could exploit this vulnerability to bypass input validation mechanisms, interfere with the application logic, or even conduct more serious attacks like Cross-Site Scripting (XSS) or SQL Injection.
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
// Define a form mapping that specifies the expected parameters
val parameterForm: Form[String] = Form(
"param" -> nonEmptyText
)
def secureAction = Action { implicit request =>
parameterForm.bindFromRequest.fold(
formWithErrors => {
// Handle the case where the form data does not match the expected format
BadRequest("Invalid parameter")
},
parameter => {
// The form data is valid, so we can safely use the parameter
Ok("Received parameter: " + parameter)
}
)
}
The above code fixes the HTTP Parameter Pollution vulnerability by implementing a whitelist approach to only allow expected parameters.
The
parameterForm
is a form mapping that specifies the expected parameters. It uses the
nonEmptyText
constraint to ensure that the "param" parameter is a non-empty string.
The
secureAction
method uses the
bindFromRequest
method of the form to bind the request parameters to the form. If the form data does not match the expected format (i.e., if the "param" parameter is missing or is not a non-empty string), the
fold
method will execute the first function, returning a
BadRequest
response with a message of "Invalid parameter".
If the form data is valid, the
fold
method will execute the second function, which uses the parameter in the application logic. Because the form ensures that the parameter meets the expected format and constraints, we can safely use the parameter without worrying about HTTP Parameter Pollution.
This approach effectively prevents the injection of extra parameters into the HTTP communication protocol, thereby preventing unexpected behavior on the server.