Skip to main content

Insecure authentication method - NTLM

Need

Implementation of a secure authentication method

Context

  • Usage of Scala for building scalable and high-performance applications
  • Usage of play.api.libs.ws for making HTTP requests in a Play Framework application
  • Usage of play.api.mvc for handling HTTP requests and responses in Play Framework
  • Usage of global execution context for concurrent programming in Scala
  • Usage of javax.inject.Inject for dependency injection in Java

Description

Non compliant code

import play.api.libs.ws._
import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
import javax.inject.Inject

class HomeController @Inject()(ws: WSClient) extends Controller {

def index = Action.async {
val complexRequest: WSRequest =
ws.url("http://example.com")
.withAuth("user", "password", WSAuthScheme.NTLM)
.withFollowRedirects(true)

complexRequest.get().map { response =>
Ok("Feed title: " + (response.json \\ "title").as[String])
}
}
}

In the above Scala code, we are using the Play Framework to make a web request to a URL (http://example.com) using the NTLM authentication scheme. This is done through the withAuth function that takes in three arguments: the username, the password, and the authentication scheme. In this case, the authentication scheme is WSAuthScheme.NTLM.

The use of NTLM authentication is considered insecure due to several vulnerabilities associated with it. These vulnerabilities include:

  1. Relay Attacks: An attacker can use the NTLM responses to authenticate to other servers using the same credentials. This is possible because NTLM does not bind the authentication to a specific server, allowing the attacker to forward the client's credentials to another server.

  2. Man-in-the-Middle Attacks: NTLM is vulnerable to Man-in-the-Middle (MitM) attacks because it does not provide server authentication. An attacker can position themselves in the middle of the client-server communication, intercept the NTLM messages, and impersonate the server or the client.

  3. Brute Force Attacks: NTLM uses a weak encryption algorithm that can be easily cracked using brute force attacks. Once the NTLM hash is obtained, an attacker can use a powerful machine to crack the hash and obtain the plaintext password.

The use of NTLM authentication in this code makes the application vulnerable to these security flaws. It is recommended to replace NTLM with a more secure authentication method like Kerberos or OAuth.

Steps

  • Replace the usage of NTLM authentication with a more secure authentication method, such as OAuth or JWT.
  • Ensure that the authentication method used supports strong encryption and secure communication protocols.
  • Implement proper authentication and authorization mechanisms to protect against relay attacks, man-in-the-middle attacks, and brute force attacks.
  • Regularly update and patch the authentication libraries and frameworks used in the application to address any known security vulnerabilities.
  • Conduct regular security assessments and penetration testing to identify and mitigate any potential security weaknesses in the authentication process.

Compliant code

import play.api.libs.ws._
import play.api.mvc._
import scala.concurrent.ExecutionContext.Implicits.global
import javax.inject.Inject
import play.api.libs.oauth.{OAuthCalculator, ConsumerKey, RequestToken}

class HomeController @Inject()(ws: WSClient) extends Controller {

val consumerKey = ConsumerKey("key", "secret")
val requestToken = RequestToken("token", "secret")

def index = Action.async {
val complexRequest: WSRequest =
ws.url("http://example.com")
.sign(OAuthCalculator(consumerKey, requestToken))
.withFollowRedirects(true)

complexRequest.get().map { response =>
Ok("Feed title: " + (response.json \\ "title").as[String])
}
}
}

The previous code was vulnerable due to the use of the insecure NTLM authentication method. This has been replaced with OAuth, a more secure authentication method.

The withAuth method has been replaced with the sign method, which is used to sign the request with the OAuth credentials. The OAuthCalculator is used to create a signature calculator with the provided consumer key and request token.

The ConsumerKey and RequestToken are placeholders and should be replaced with your actual OAuth credentials. These credentials are typically obtained from the service you're authenticating with and should be stored securely.

This change helps to protect against several types of attacks, including relay attacks, man-in-the-middle attacks, and brute force attacks. It's also recommended to regularly update and patch the authentication libraries and frameworks used in the application, and to conduct regular security assessments and penetration testing.

References