Saltar a contenido

Insecure TLS Certificate Validation

Validación Insegura de Certificados TLS

Descripción

La validación insegura de certificados TLS es una vulnerabilidad en el establecimiento de conexiones seguras entre un cliente y un servidor. TLS (Transport Layer Security) es un protocolo criptográfico que proporciona comunicación segura a través de Internet. Cuando un cliente se conecta a un servidor a través de TLS, comprueba el certificado digital del servidor para verificar su identidad y asegurarse de que la conexión sea segura.

La validación insegura de certificados TLS se produce cuando el cliente no valida correctamente el certificado del servidor, permitiendo a un atacante hacerse pasar por el servidor e interceptar o modificar la comunicación entre el cliente y el servidor. Esto puede llevar a que la información confidencial sea robada, modificada o expuesta.

Las siguientes son algunas debilidades comunes en la validación de certificados TLS:

  • Certificados Caducados: Un certificado que ha expirado ya no se considera válido. Sin embargo, un cliente que no verifique la fecha de caducidad del certificado puede aceptar un certificado caducado, que podría haber sido revocado o comprometido.

  • Certificados Autofirmados: Un certificado autofirmado es un certificado que ha sido firmado por la misma entidad que lo emitió. Dado que no hay un tercero independiente para verificar la autenticidad del certificado, un cliente que confía en un certificado autofirmado podría ser vulnerable a un ataque de tipo "man-in-the-middle".

  • Certificados de Host Incorrecto: Un certificado se emite para un nombre de dominio o dirección IP específica. Si un cliente se conecta a un servidor con un certificado que no coincide con el nombre de host o la dirección IP, el cliente podría ser vulnerable a un ataque "man-in-the-middle".

  • Certificados Raíz no Confiables: Un certificado raíz es el certificado de nivel superior en una cadena de certificados, y se utiliza para validar la autenticidad de todos los certificados en la cadena. Si un cliente no confía en el certificado raíz utilizado por el servidor, puede aceptar un certificado fraudulento firmado por un certificado raíz no confiable.

  • Certificados Revocados: Un certificado puede ser revocado si ha sido comprometido o si ya no se considera confiable. Un cliente que no comprueba el estado de revocación del certificado podría aceptar un certificado revocado, lo que podría usarse para realizar un ataque "man-in-the-middle".

import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.SecureRandom;

public class HttpsRequestWithoutTlsVerification {
    public static void main(String[] args) throws Exception {
        // Disable SSL/TLS verification
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        }};
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new SecureRandom());

        // Create connection and set SSL context
        URL url = new URL("https://example.com");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setSSLSocketFactory(sslContext.getSocketFactory());

        // Send HTTP request
        conn.setRequestMethod("GET");
        int responseCode = conn.getResponseCode();
        System.out.println("Response code: " + responseCode);
    }
}
import 'dart:io';

void main() async {
  var client = HttpClient();

  // Disable SSL certificate validation
  client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;

  // Make HTTP request
  var request = await client.getUrl(Uri.parse('https://example.com'));
  var response = await request.close();
  print('Response code: ${response.statusCode}');
  client.close();
}

Recomendación

Para mitigar el riesgo de una validación insegura de certificados TLS, se recomienda que la aplicación implemente mecanismos de validación de certificados seguros tanto en el cliente como en el servidor. Esto incluye:

  • Comprobar la validez del certificado del servidor para asegurar que no ha caducado, no ha sido revocado y ha sido emitido por una autoridad de certificación de confianza.
  • Configurar la verificación del nombre de host para garantizar que el certificado coincida con el nombre de dominio del servidor y evitar así aceptar certificados con nombres de host no válidos.
  • Utilizar autoridades de certificación de confianza y evitar los certificados autofirmados o certificados raíz no confiables.

Además, es importante mantener la aplicación y cualquier biblioteca o marco de trabajo utilizado actualizados con los últimos parches de seguridad, y probar regularmente la postura de seguridad de la aplicación para identificar cualquier vulnerabilidad que pueda existir.

Enlaces

Estándares

  • PCI_STANDARDS:
    • REQ_2_2
    • REQ_4_2
    • REQ_6_2
    • REQ_6_3
    • REQ_6_4
    • REQ_11_3
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_6_7
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5