Sensitive information sent via URL parameters - Scala

Sensitive information sent via URL parameters - Scala

Need

Protection of sensitive information during transmission

Context

  • Usage of Scala for functional and object-oriented programming in the JVM
  • Usage of play.api.mvc for handling HTTP requests and responses in Play Framework
  • Usage of views.html.user for rendering HTML templates in a user interface
  • Usage of UserService for managing user-related operations

Description

Non compliant code

        import play.api.mvc._

object HomeController extends Controller {
  def getUserDetails(userId: String) = Action {
    val user = UserService.getUser(userId)
    Ok(views.html.user(user))
  }
}
        
        

The above code snippet is a Scala Play Framework controller action that retrieves user details based on a user ID passed as a URL parameter. The getUserDetails function in the HomeController takes a userId as a parameter, retrieves the user details from the UserService, and then sends these details to a view to be rendered.

The view then displays the user's name, email, and address.

This code is vulnerable because it sends sensitive user information (name, email, address) via URL parameters using the GET method.

This means that:

- The sensitive user information is stored in clear text in the browser history, making it accessible to anyone with access to the user's browser.
- The sensitive user information is sent to external sites via the referrer HTTP header. This can lead to data leakage if the user navigates to an external site from the page displaying the user details.
- The sensitive user information is sent to external sites via the search bar if the browser interprets the URL as a query. This can lead to data leakage if the user performs a search from the page displaying the user details.
- The sensitive user information is visible to scripts running on the browser that may belong to third-parties. This can lead to data leakage if there are malicious scripts running on the user's browser.

Steps

  • Avoid sending sensitive information via URL parameters.
  • Use the POST method instead of the GET method to send sensitive information.
  • Encrypt sensitive information before sending it over the network.
  • Store sensitive information securely on the server-side.
  • Implement access controls to restrict access to sensitive information.
  • Implement secure communication protocols (e.g., HTTPS) to protect sensitive information during transit.
  • Implement secure session management to handle user authentication and authorization.
  • Implement input validation and sanitization to prevent injection attacks.
  • Implement output encoding to prevent cross-site scripting (XSS) attacks.
  • Educate developers about secure coding practices and perform regular security audits.

Compliant code

        import play.api.mvc._
import play.api.libs.json._

object HomeController extends Controller {
  def getUserDetails = Action(parse.json) { request =>
    val userId = (request.body \\ "userId").as[String]
    val user = UserService.getUser(userId)
    Ok(views.html.user(user))
  }
}
        
        

The original code was vulnerable because it was sending sensitive information (the user ID) via URL parameters using the GET method. This is a security risk because the information is stored in clear text in the browser history, sent to external sites via the referrer HTTP header, sent to external sites via the search bar if the browser interprets the URL as a query, and visible to scripts running on the browser that may belong to third-parties.

The revised code fixes this vulnerability by changing the method from GET to POST and sending the user ID in the body of the request instead of the URL. This is done by using the Action(parse.json) method to parse the JSON body of the request, and then extracting the user ID with (request.body \\ "userId").as[String].

This change ensures that the user ID is not exposed in the URL, making it more secure. However, it's important to note that this is just one step in securing the application. Other measures should also be taken, such as encrypting sensitive information before sending it over the network, storing sensitive information securely on the server-side, implementing access controls, secure communication protocols (e.g., HTTPS), secure session management, input validation and sanitization, output encoding, and educating developers about secure coding practices.

References