Skip to main content

Use of insecure channel - Source code

Need

Secure transmission of customer information

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet for building Java web applications
  • Usage of java.io for input and output operations in Java

Description

Non compliant code

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class InsecureServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String customerName = request.getParameter("customerName");
String customerAddress = request.getParameter("customerAddress");
String customerEmail = request.getParameter("customerEmail");

// Write the customer details to a file
PrintWriter out = new PrintWriter(new FileWriter("customerDetails.txt", true));
out.println("Name: " + customerName);
out.println("Address: " + customerAddress);
out.println("Email: " + customerEmail);
out.close();
}
}

The above Java Servlet code is vulnerable because it transmits sensitive customer information over an insecure channel, which does not use encryption.

In the doPost method, we are getting customer details from the request parameters. These details include the customer's name, address, and email. This information is sensitive and should be protected.

However, in this code, the customer details are being written to a file without any encryption. This means that if an attacker is able to intercept the transmission of this data or gain access to the file where it is stored, they would be able to read and misuse this information.

Moreover, the information is being transmitted over HTTP, which is not secure. HTTP traffic can be easily intercepted and read by attackers. To secure the transmission of sensitive information, it should be sent over HTTPS, which encrypts the data.

In addition, the code does not implement any form of access control or authentication. This means that any user, regardless of whether they are authenticated or have the necessary permissions, can access and potentially manipulate the customer information.

Steps

  • Implement secure communication channel using encryption
  • Use HTTPS instead of HTTP for transmitting customer information
  • Encrypt the customer details before writing to a file
  • Implement secure storage for customer details

Compliant code

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;

public class SecureServlet extends HttpServlet {

private static final String ALGO = "AES";
private static final byte[] keyValue =
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String customerName = request.getParameter("customerName");
String customerAddress = request.getParameter("customerAddress");
String customerEmail = request.getParameter("customerEmail");

// Encrypt the customer details
String encryptedName = encrypt(customerName);
String encryptedAddress = encrypt(customerAddress);
String encryptedEmail = encrypt(customerEmail);

// Write the encrypted customer details to a file
PrintWriter out = new PrintWriter(new FileWriter("customerDetails.txt", true));
out.println("Name: " + encryptedName);
out.println("Address: " + encryptedAddress);
out.println("Email: " + encryptedEmail);
out.close();
}

public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}

private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
}

The above code is a secure version of the previous servlet. It uses HTTPS instead of HTTP for transmitting customer information. This is done by the servlet container and not shown in the code.

The customer details are encrypted before they are written to a file. This is done using the Advanced Encryption Standard (AES) algorithm. A secret key is used for the encryption. The encrypted data is then encoded using Base64 before it is written to the file.

The encrypt method takes a string as input and returns the encrypted string. The generateKey method generates the secret key used for encryption.

Please note that the secret key should be stored securely and not be hard-coded as shown in this example. Also, the use of the sun.misc.BASE64Encoder is not recommended as it is a part of Sun's proprietary APIs and may not be available in all JVMs. You can use java.util.Base64 instead in Java 8 and later.

References