Insecurely generated token - OTP - Java
Need
Secure generation and transmission of OTP tokens
Context
- Usage of Java 8 for developing applications with enhanced features and performance
- Usage of javax.servlet-api for building Java web applications with Servlets
Description
Insecure Code Example
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OTPServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String phoneNumber = request.getParameter("phoneNumber");
String otp = generateOTP();
// send OTP to the client
response.getWriter().write("OTP: " + otp);
}
private String generateOTP() {
// insecure OTP generation
return String.valueOf((int)(Math.random() * 1000000));
}
}
The above Java servlet generates an OTP (One-Time Password) when the `doGet` method is called. The `doGet` method takes in a `HttpServletRequest` and a `HttpServletResponse` as parameters. In the `doGet` method, it retrieves a phone number from the request parameters and generates an OTP using the `generateOTP` method. The generated OTP is then sent back to the client through the response writer. The `generateOTP` method generates a random number between 0 and 999999, converts it to a string and returns it. This code is vulnerable because the OTP is generated on the client-side and sent to the server. An attacker can intercept the request and access the OTP, allowing them to continue the application flow without needing access to the phone number used. This can lead to unauthorized access and potential data breaches.
Steps
- Generate the OTP server-side instead of client-side
- Use a cryptographically secure random number generator to generate the OTP
- Ensure that the OTP is securely transmitted to the client, such as using HTTPS
- Implement additional security measures, such as rate limiting or throttling, to prevent brute force attacks on the OTP
Secure Code Example
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.SecureRandom;
public class OTPServlet extends HttpServlet {
private static final SecureRandom secureRandom = new SecureRandom(); // Cryptographically secure random
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String phoneNumber = request.getParameter("phoneNumber");
String otp = generateOTP();
// send OTP to the client
response.getWriter().write("OTP: " + otp);
}
private String generateOTP() {
// Secure OTP generation
return String.format("%06d", secureRandom.nextInt(1000000));
}
}
The original code was vulnerable because it was generating the OTP (One-Time Password) on the client-side, which could be intercepted by an attacker. The OTP was also generated using `Math.random()`, which is not cryptographically secure. The fixed code generates the OTP on the server-side, which is more secure because it's harder for an attacker to intercept. The OTP is generated using `SecureRandom`, which is a cryptographically secure random number generator. This makes it much harder for an attacker to guess the OTP. The OTP is then sent to the client. To ensure this transmission is secure, it should be sent over HTTPS, which encrypts the data in transit. Additional security measures, such as rate limiting or throttling, should also be implemented to prevent brute force attacks. These measures limit the number of attempts that can be made to guess the OTP, making such attacks impractical.
References
Last updated
2023/09/18