🌐 DNS 이름에 의존한 보안 결정 KISA A-7 · DNS lookup 기반 보안 결정
서버가 호스트명을 신뢰해 클라이언트를 인가합니다. 클라이언트 IP의 역DNS(PTR)가
.trusted.example로 끝나면 받아 주거나, 호스트명을 한 번 해석한 IP를 신뢰합니다. 둘 다 공격자가 조작할 수 있습니다.
① 역DNS 접미사 / 1회 해석으로 인가 VULNERABLE
공격을 고르세요. PTR 스푸핑: 공격자가 자기 IP의 PTR 레코드를
x.trusted.example로 지정합니다. DNS 리바인딩(TOCTOU): 검사 시점엔 허용 IP로 해석되다가, 사용 시점엔 내부 IP로 재해석됩니다.
② 암호학적 인증 + 실제 IP 검증 SECURE
수정본은 이름을 절대 신뢰하지 않습니다. Bearer 토큰/mTLS 클라이언트 인증서를 요구하고, 실제 접속 IP를 숫자 허용목록으로 검사하며, 내부/링크로컬 대역을 차단하고, 해석된 IP를 연결 내내 핀(재해석 금지)합니다.
③ 취약 vs 안전 코드
VULNERABLE
// trust the reverse-DNS of the client IP
String ptr = InetAddress
.getByName(clientIp)
.getCanonicalHostName(); // attacker-set PTR
if (ptr.endsWith(".trusted.example")) {
allowAdmin(); // ⚠ spoofable
}
// or: resolve once, trust forever (rebinding)
InetAddress ip = InetAddress.getByName(host); // check
if (allowList.contains(ip)) {
// ...later, library re-resolves host...
httpClient.get("https://" + host + "/x"); // use
} // ⚠ TOCTOU
SECURE
// 1) authenticate, don't trust a name
verifyMtlsClientCert(conn); // or bearer token
// 2) validate the ACTUAL connecting IP (numeric)
InetAddress ip = conn.getRemoteAddr();
if (isInternalOrLinkLocal(ip)) deny(); // 169.254/16,
// 10/8, 127/8...
if (!IP_ALLOWLIST.contains(ip)) deny();
// 3) pin the resolved IP for the whole request
InetAddress pinned = resolveOnce(host);
if (isInternalOrLinkLocal(pinned)) deny();
httpClient.connectTo(pinned, host); // no re-lookup
왜 위험한가: DNS(특히 역방향/PTR)는 존을 소유한 자—자기 IP에 대해서는 흔히 공격자—가 제어하고, 검사와 사용 사이에 해석이 바뀔 수 있어(리바인딩) 이름은 신원·위치의 증거가 못 됩니다. 이는
169.254.169.254 클라우드 메타데이터로 가는 SSRF의 토대입니다. 방어 핵심: 이름이 아니라 토큰/mTLS로 인증 · 실제 접속 IP(숫자 허용목록)로 인가 · 내부/링크로컬/루프백 대역 차단 · 1회 해석 후 IP 핀 · 해석 후 재검증.
⚠️ 교육용 시뮬레이션입니다. 모든 DNS 조회·IP·서버는 페이지 내부 mock이며 실제 DNS 질의·네트워크 연결·메타데이터 엔드포인트에 접근하지 않습니다.