Business information leak - Financial Information - Scala

Business information leak - Financial Information - Scala

Need

Protection of sensitive financial information from unauthorized access or disclosure

Context

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

Description

Non compliant code

        import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global

class BusinessController extends Controller {

  def getBusinessInfo() = Action.async { implicit request =>
    val businessInfo = BusinessModel.find.all() //retrieve all business information
    Ok(Json.toJson(businessInfo)) //return all business information as JSON
  }
}

case class BusinessModel(mail: String, paymentReference: String, description: String, totalValue: Double, productInfo: String, collectorBusiness: String, payerRole: String)

object BusinessModel {
  val find = {
    // Simulate a database find helper.
    new {
      def all(): List[BusinessModel] = {
        // Retrieve all business information from the database.
        List(
          BusinessModel("mail@example.com", "123456", "Payment for services", 100.0, "Product A", "Business A", "Role A"),
          BusinessModel("mail2@example.com", "654321", "Payment for products", 200.0, "Product B", "Business B", "Role B")
        )
      }
    }
  }
}
        
        

The above code snippet represents a Scala backend application that uses the Play framework. This application has a serious vulnerability related to the leakage of sensitive business information.

The getBusinessInfo() method in the BusinessController class retrieves all business information from the database and returns it as a JSON object. This information includes sensitive data such as mail, payment reference, description, total value, product information, collector's line of business, and payer's role.

The BusinessModel case class represents the structure of the business information in the database. The all() method in the find object simulates a database helper function that retrieves all business information.

This code is vulnerable because it indiscriminately exposes all business information to any client that sends a request to the getBusinessInfo() endpoint. This can result in a serious information leak if an unauthorized user gains access to this endpoint.

Steps

  • Avoid returning sensitive business information directly in the response.
  • Implement proper access control mechanisms to restrict access to sensitive information.
  • Use encryption or tokenization techniques to protect sensitive information in transit and at rest.
  • Implement data masking or redaction techniques to hide sensitive information from unauthorized users.
  • Regularly review and update the access controls and permissions for accessing business information.
  • Implement logging and monitoring mechanisms to detect and respond to any unauthorized access attempts.
  • Conduct regular security assessments and penetration testing to identify and address any vulnerabilities in the application.
  • Educate developers and users about the importance of handling sensitive information securely.

Compliant code

        import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.libs.json._

class BusinessController extends Controller {

  def getBusinessInfo() = Action.async { implicit request =>
    val businessInfo = BusinessModel.find.all() //retrieve all business information
    val safeBusinessInfo = businessInfo.map(info => info.copy(mail = "", paymentReference = "")) //remove sensitive information
    Ok(Json.toJson(safeBusinessInfo)) //return all business information as JSON
  }
}

case class BusinessModel(mail: String, paymentReference: String, description: String, totalValue: Double, productInfo: String, collectorBusiness: String, payerRole: String)

object BusinessModel {
  val find = {
    // Simulate a database find helper.
    new {
      def all(): List[BusinessModel] = {
        // Retrieve all business information from the database.
        List(
          BusinessModel("mail@example.com", "123456", "Payment for services", 100.0, "Product A", "Business A", "Role A"),
          BusinessModel("mail2@example.com", "654321", "Payment for products", 200.0, "Product B", "Business B", "Role B")
        )
      }
    }
  }
}
        
        

The updated code now includes a step to remove sensitive information before returning the business information. This is done by creating a new list of BusinessModel objects where the mail and paymentReference fields are set to an empty string. This effectively masks these sensitive fields from the response.

This is a simple and effective way to prevent sensitive business information from being leaked. However, it's important to note that this is just one part of a comprehensive security strategy. Other measures that should be taken include:

- Implementing proper access control mechanisms to restrict access to sensitive information.
- Using encryption or tokenization techniques to protect sensitive information in transit and at rest.
- Regularly reviewing and updating the access controls and permissions for accessing business information.
- Implementing logging and monitoring mechanisms to detect and respond to any unauthorized access attempts.
- Conducting regular security assessments and penetration testing to identify and address any vulnerabilities in the application.
- Educating developers and users about the importance of handling sensitive information securely.

References