Use of an insecure channel - Scala

Use of an insecure channel - Scala

Need

Secure communication channel

Context

  • Usage of Scala for functional and object-oriented programming in the JVM
  • Usage of play.api.libs.ws for making HTTP requests in Play Framework

Description

Non compliant code

        import play.api.libs.ws.WSClient

class InsecureChannel {
  val ws: WSClient

  def sendData(data: String, url: String) = {
    ws.url(url).post(data)
  }
}
        
        

The above code represents a simple Scala class that uses Play Framework's WSClient to send data to a specified URL.

The sendData method takes in a data string and a URL, and it sends the data to the URL using an HTTP POST request.

The vulnerability lies in the fact that the data is sent over an unencrypted channel. This means that any data sent using this method could potentially be intercepted and read by malicious third parties. This is particularly risky if the data being sent contains sensitive information, such as user credentials or personal data.

The ws.url(url).post(data) line is where the data is actually sent. Here, the post method is called on the result of ws.url(url), which creates a request to the specified URL. The data is included in the body of the request, and no encryption is applied to it before it is sent.

This vulnerability could be exploited in a 'Man-in-the-Middle' (MITM) attack, where a malicious party intercepts the data being sent between the client and the server. Because the data is not encrypted, the attacker would be able to read and potentially misuse it.

Steps

  • Enable HTTPS for the application
  • Use secure protocols (e.g., TLS) for transmitting data
  • Implement SSL/TLS certificate validation
  • Ensure the server-side application verifies the client's identity
  • Implement secure communication protocols (e.g., HTTPS) for external API calls
  • Encrypt sensitive data before transmitting
  • Implement secure authentication and authorization mechanisms

Compliant code

        import play.api.libs.ws.WSClient
import play.api.libs.ws.ahc.AhcWSClientConfigFactory
import play.api.libs.ws.ahc.AhcWSClient
import play.api.libs.ws.ahc.AhcConfigBuilder
import play.api.libs.ws.ahc.AhcWSClientConfig
import com.typesafe.config.ConfigFactory
import play.shaded.ahc.org.asynchttpclient.DefaultAsyncHttpClientConfig

class SecureChannel {
  val ws: WSClient

  def sendData(data: String, url: String) = {
    val config = new DefaultAsyncHttpClientConfig.Builder()
    config.setUseInsecureTrustManager(false)
    val ahcBuilder = new AhcConfigBuilder(AhcWSClientConfigFactory.forConfig(ConfigFactory.load(), config.build()))
    val ahcConfig = ahcBuilder.build()
    val wsClient = AhcWSClient(ahcConfig)
    wsClient.url(url).withRequestFilter(WSClientFilter()).withHttpHeaders(("Content-Type", "application/json")).post(data)
  }
}
        
        

The above code is a secure version of the previous insecure channel. Here, we are using the Play Framework's WSClient to send data over the network. The WSClient is configured to use a secure connection (HTTPS) and to validate SSL/TLS certificates.

The setUseInsecureTrustManager(false) method is used to disable the insecure trust manager, which means that the client will validate the server's SSL/TLS certificate. This prevents man-in-the-middle attacks where an attacker could intercept the communication by presenting a fake certificate.

The AhcConfigBuilder and AhcWSClientConfigFactory are used to build a configuration for the WSClient that includes the secure settings.

The wsClient.url(url).withRequestFilter(WSClientFilter()).withHttpHeaders(("Content-Type", "application/json")).post(data) line is used to send the data. The withRequestFilter(WSClientFilter()) method is used to add a filter that can modify the request before it is sent. In this case, we are not modifying the request, but this could be used to add additional security measures such as signing the request. The withHttpHeaders(("Content-Type", "application/json")) method is used to set the content type of the request to JSON.

This code ensures that the data is sent over a secure channel and that the server's identity is verified, which fixes the vulnerability.

References