Insecure Network Communication
Why is this important?
Ensuring that the data in transit is secured between users and your application is the most fundamental security requirement. If this security control is not in place then all bets are off and attackers have many ways to attack your users.
Check out this video for a high-level explanation:
Fixing Insecure Network Communication
Option A: Secure the TrustManager
Empty TrustManager implementations are often used to connect easily to a host that is not signed by a root certificate authority. As a consequence, this is vulnerable to Man-in-the-middle attacks since the client will trust any certificate.
A TrustManager allowing specific certificates (based on a TrustStore for example) should be built.
Detailed information for a proper implementation is available here:
Detailed Instructions
- Go through the issues that GuardRails identified in the PR.
- Look for code like this:
class TrustAllManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
//Trust any client connecting (no certificate validation)
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
//Trust any remote server (no certificate validation)
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
- Replace it with:
KeyStore ks = //Load keystore containing the certificates trusted
SSLContext sc = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);
- Test it
- Ship it 🚢 and relax 🌴
Option B: Secure the HostnameVerifier
A HostnameVerifier
that accept any host are often use because of certificate
reuse on many hosts. As a consequence, this is vulnerable to
Man-in-the-middle attacks
since the client will trust any certificate.
A TrustManager
allowing specific certificates (based on a truststore for example) should be built.
Wildcard certificates should be created for reused on multiples subdomains.
Detailed information for a proper implementation is available at:
Detailed Instructions
- Go through the issues that GuardRails identified in the PR.
- Look for code like this:
public class AllHosts implements HostnameVerifier {
public boolean verify(final String hostname, final SSLSession session) {
return true;
}
}
- Replace it with:
KeyStore ks = //Load keystore containing the certificates trusted
SSLContext sc = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);
- Test it
- Ship it 🚢 and relax 🌴
Option C: Use TLS over SSL
SSL has been considered insecure and it is recommended to switch to TLS.
Detailed Instructions
- Go through the issues that GuardRails identified in the PR.
- Look for code like this:
SSLContext.getInstance("SSL");
- Replace it with:
SSLContext.getInstance("TLS");
- Configure
https.protocols
JVM option to include TLSv1.2 - Test it
- Ship it 🚢 and relax 🌴
Option D: Use an encrypted communications channel
The communication channel used is not encrypted. The traffic could be read by an attacker intercepting the network traffic. Beyond using an SSL socket, you need to make sure your use of SSLSocketFactory does all the appropriate certificate validation checks to make sure you are not subject to man-in-the-middle attacks. Please read the OWASP Transport Layer Protection Cheat Sheet for details on how to do this correctly.
- OWASP: Top 10 2010-A9-Insufficient Transport Layer Protection
- OWASP: Top 10 2013-A6-Sensitive Data Exposure
- OWASP: Transport Layer Protection Cheat Sheet
- WASC-04: Insufficient Transport Layer Protection
- CWE-319: Cleartext Transmission of Sensitive Information
Detailed Instructions
- Go through the issues that GuardRails identified in the PR.
- Look for code like this:
Socket soc = new Socket("www.google.com",80);
or:
ServerSocket soc = new ServerSocket(1234);
- Replace it with:
Socket soc = SSLSocketFactory.getDefault().createSocket("www.google.com", 443);
or:
ServerSocket soc = SSLServerSocketFactory.getDefault().createServerSocket(1234);
- Test it
- Ship it 🚢 and relax 🌴
Option E: Ensure that the SMTP SSL connection verifies the certificate
Server identity verification is disabled when making SSL connections. Some email libraries that enable SSL connections do not verify the server certificate by default. This is equivalent to trusting all certificates. When trying to connect to the server, this application would readily accept a certificate issued to "victim.com". The application would now potentially leak sensitive user information on a broken SSL connection to the victim server.
References:
Detailed Instructions
- Go through the issues that GuardRails identified in the PR.
- Look for code like this:
Email email = new SimpleEmail();
email.setHostName("smtp.servermail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setFrom("[email protected]");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("[email protected]");
email.send();
- And add this code snippet:
email.setSSLCheckServerIdentity(true);
- Test it
- Ship it 🚢 and relax 🌴