신뢰 검증이 비활성화된 TLS 설정

신뢰 검증이 비활성화된 TLS 설정

설명

TLS 연결에서 모든 인증서를 신뢰하거나 모든 호스트명을 허용하면 중간자 공격(MITM)에 취약해집니다. X509TrustManager의 검증 메서드를 비워 두거나 HostnameVerifier가 항상 true를 반환하면 서버 인증이 사실상 제거됩니다.

잠재적 영향

  • 공격자가 위조 인증서를 사용해 TLS 연결을 가로챌 수 있습니다.
  • 민감한 데이터, 세션 토큰, API 요청/응답이 도청 또는 변조될 수 있습니다.
  • 테스트용 우회 설정이 운영 환경까지 유입되면 전체 통신 보안이 무력화될 수 있습니다.

해결 방법

  • 기본 신뢰 저장소와 기본 HostnameVerifier를 사용하고, 특정 환경에서만 예외를 두지 않습니다.
  • 테스트용 self-signed 인증서가 필요하면 별도 trust store를 구성합니다.
  • 모든 인증서 또는 모든 호스트명을 허용하는 커스텀 verifier, trust manager를 사용하지 않습니다.

예시

변경 전

java
import javax.net.ssl.HttpsURLConnection;

public class UnsafeHostnameVerifier {
    void configure(HttpsURLConnection conn) {
        conn.setHostnameVerifier((hostname, session) -> true);
    }
}

변경 후

java
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;

public class SafeTlsVerifier {
    void configure(HttpsURLConnection conn) {
        HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
        conn.setHostnameVerifier(verifier);
    }
}

설명:

  • 변경 전: 호스트명이 무엇이든 항상 true를 반환하므로 서버 인증서의 대상 검증이 완전히 무력화됩니다.
  • 변경 후: 기본 hostname verifier를 사용해 TLS 라이브러리의 정상 검증 흐름을 유지합니다.

다른 검증 우회 설정

  • new X509TrustManager() { ... }에서 checkClientTrusted, checkServerTrusted를 비워 두면 해당 인증서의 신뢰 검증을 건너뜁니다.
  • 이름 있는 class AlwaysTrueVerifier implements HostnameVerifier든 익명 new HostnameVerifier() { ... return true; }든 항상 허용하는 구현은 호스트명 검증을 우회합니다.
  • Kotlin의 HostnameVerifier { _, _ -> true }도 같은 위험이 있습니다. object : HostnameVerifier { ... }나 object : X509TrustManager { ... }로 구현할 때도 실제 검증을 수행해야 합니다.

참조