Insecure functionality - File Creation - Scala

Insecure functionality - File Creation - Scala

Need

Enforce server-side validation and authorization for file creation functionality

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 java.io for input and output operations in Java programming

Description

Non compliant code

        package controllers

import play.api.mvc._
import java.io._

class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {

  def createFile = Action { implicit request: Request[AnyContent] =>
    val fileName = request.body.asFormUrlEncoded.get("fileName").head
    val fileContent = request.body.asFormUrlEncoded.get("fileContent").head

    val file = new File(fileName)
    val bw = new BufferedWriter(new FileWriter(file))
    bw.write(fileContent)
    bw.close()

    Ok("File created.")
  }
}
        
        

The above Scala code represents a Play Framework controller action createFile that creates a file with a given name and content. The name and content of the file are retrieved from the request body.

The vulnerability here is that there is no server-side check to validate if the authenticated user has the necessary permissions to create a file. The check is only performed on the client-side by disabling the button, which can easily be bypassed by a malicious user. This means that even if the button is disabled on the client-side, the server will still process the request to create the file if it receives one, leading to an insecure functionality vulnerability.

The createFile function gets the fileName and fileContent from the request body without validating if the user has the necessary permissions to create a file. It then creates a new File object with the fileName, writes the fileContent to it, and finally closes the file. This results in a new file being created every time the createFile function is called, regardless of the user's permissions.

Steps

  • Implement server-side validation to check if the user has the necessary permissions to create a file.
  • Remove the front-end restriction on the create file button and rely solely on server-side validation.
  • Ensure that the file name and content are properly validated and sanitized to prevent any malicious input.
  • Consider implementing a file naming convention to avoid potential security risks.
  • Use a secure file storage location and restrict access permissions to prevent unauthorized access to the created files.

Compliant code

        package controllers

import play.api.mvc._
import java.io._
import javax.inject.Inject
import services.UserService

class HomeController @Inject()(val controllerComponents: ControllerComponents, userService: UserService) extends BaseController {

  def createFile = Action { implicit request: Request[AnyContent] =>
    val user = userService.getCurrentUser(request)
    if (user.canCreateFiles) {
      val fileName = request.body.asFormUrlEncoded.get("fileName").head
      val fileContent = request.body.asFormUrlEncoded.get("fileContent").head

      // Validate and sanitize the file name and content
      if (isValidFileName(fileName) && isValidFileContent(fileContent)) {
        val file = new File(s"/secure/location/$fileName")
        val bw = new BufferedWriter(new FileWriter(file))
        bw.write(fileContent)
        bw.close()

        Ok("File created.")
      } else {
        BadRequest("Invalid file name or content.")
      }
    } else {
      Forbidden("You do not have permission to create files.")
    }
  }

  private def isValidFileName(fileName: String): Boolean = {
    // Implement your file name validation logic here
  }

  private def isValidFileContent(fileContent: String): Boolean = {
    // Implement your file content validation logic here
  }
}
        
        

The updated code now includes server-side validation to check if the authenticated user has the necessary permissions to create a file. This is done by calling userService.getCurrentUser(request) to get the current user and then checking the canCreateFiles property of the user.

The file name and content are also validated and sanitized by the isValidFileName and isValidFileContent methods respectively. These methods should contain your own logic for validating and sanitizing the file name and content.

The file is now created in a secure location ( /secure/location/) and the file name is appended to this path. This helps to prevent unauthorized access to the created files.

If the user does not have permission to create files, a Forbidden response is returned. If the file name or content is invalid, a BadRequest response is returned. If the file is created successfully, an Ok response is returned.

References