Skip to main content

Hidden fields manipulation

Need

Protection against hidden field manipulation

Context

  • Usage of Scala for building scalable and functional applications
  • Usage of play.api.mvc for handling HTTP requests and responses in Play Framework

Description

Non compliant code

import play.api.mvc._

object Application extends Controller {

def save = Action { implicit request =>
val form = request.body.asFormUrlEncoded
val hiddenField = form.get("hiddenField").headOption
hiddenField match {
case Some(value) => Ok("Hidden field value: " + value)
case None => BadRequest("Missing hidden field")
}
}
}

In the above code, we have a simple Play Framework controller named Application. This controller has a single action named save. This action is vulnerable to hidden fields manipulation.

The save action retrieves form data from the request and attempts to extract a value for a hidden field named "hiddenField". If the field is found, the value of the field is returned in the response. If the field is not found, a BadRequest response is returned.

The vulnerability lies in the fact that the value of the "hiddenField" is trusted without any validation. An attacker can manipulate the value of the hidden field before the form is submitted. Since the application blindly trusts the value of the hidden field, this can lead to undesired behaviors.

For example, if the hidden field is used to store the ID of a database record, an attacker could change the ID before submitting the form, causing the action to operate on a different record than intended.

To mitigate this vulnerability, the application should not trust user input, even if it is from a hidden field. The application should validate all input and ensure it is in an expected format and within expected bounds. The application should also ensure that the user has the necessary permissions to perform the action they are attempting.

Steps

  • Avoid using hidden fields to store sensitive or critical information.
  • Validate and sanitize all user input, including hidden fields, before processing or using them.
  • Use server-side session management to store and retrieve sensitive or critical information instead of relying on hidden fields.
  • Implement proper access controls and authorization mechanisms to prevent unauthorized access or manipulation of hidden fields.
  • Implement server-side validation to ensure the integrity and validity of hidden field values.
  • Consider using encryption or hashing techniques to protect the confidentiality and integrity of hidden field values.
  • Regularly update and patch the Play framework and its dependencies to benefit from security fixes and improvements.
  • Perform security testing and code reviews to identify and address any potential vulnerabilities in the application.

Compliant code

import play.api.mvc._
import play.api.data._
import play.api.data.Forms._

object Application extends Controller {

case class Data(hiddenField: Option[String])

val form = Form(
mapping(
"hiddenField" -> optional(text)
)(Data.apply)(Data.unapply)
)

def save = Action { implicit request =>
form.bindFromRequest.fold(
formWithErrors => BadRequest("Invalid request"),
data => data.hiddenField match {
case Some(value) => Ok("Hidden field value: " + value)
case None => BadRequest("Missing hidden field")
}
)
}
}

The original code was vulnerable to hidden fields manipulation. This vulnerability could allow an attacker to modify fields that are invisible to the regular user and cause undesired behaviors in the application.

The fixed code uses Play Framework's form handling to bind the request data to a case class. This provides a layer of abstraction between the raw request data and the application logic, which can help to prevent manipulation of hidden fields.

The Form object is defined with a mapping that specifies the expected structure of the request data. In this case, it expects an optional hiddenField parameter. The Form object is then used to bind the request data to an instance of the Data case class.

The bindFromRequest method is used to bind the request data to the form. If the binding is successful, the form data is passed to the success function, which checks the value of the hiddenField parameter and responds accordingly. If the binding fails (for example, if the request data does not match the expected structure), the failure function is called, which responds with a "Invalid request" error.

This approach provides several layers of protection against hidden fields manipulation:

  • It validates the structure of the request data, ensuring that it matches the expected structure.
  • It sanitizes the request data by binding it to a case class, which can help to prevent injection attacks.
  • It provides a clear separation between the raw request data and the application logic, which can make it harder for an attacker to manipulate hidden fields.

In addition to these measures, it's also recommended to implement proper access controls and authorization mechanisms, use server-side session management, and regularly update and patch the Play framework and its dependencies.

References