![](/media/secure-coding/images/2024/04/16/%EC%8B%9C%ED%81%90%EC%96%B4%EC%BD%94%EB%94%A92_MHtj7UU.jpg)
소프트웨어 개발보안 가이드 분석(2021) : DNS lookup에 의존한 보안결정
공격자가 DNS 엔트리를 속일 수 있으므로 도메인명에 의존해서 보안결정(인증 및 접근 통제 등)을 하지 않아야 한다.
만약, 로컬 DNS 서버의 캐시가 공격자에 의해 오염된 상황이라면, 사용자와 특정 서버 간의 네트워크 트래픽이 공격자를 경유하도록 할 수도 있다.
또한, 공격자가 마치 동일 도메인에 속한 서버인 것처럼 위장할 수도 있다.
소프트웨어 개발보안가이드(2021), 한국인터넷진흥원
※ DNS lookup : DNS을 사용하여 도메인 이름을 IP 주소로 변환하거나, IP 주소를 도메인 이름으로 변환하는 과정을 말합니다. 이 과정은 인터넷에서 컴퓨터나 다른 장치들이 서로를 식별하고 통신할 수 있도록 도와주는 중요한 기능입니다.
소프트웨어 개발에서 보안은 절대 어그러지지 않는 것이 중요합니다. 그중에서도 DNS lookup에 의존한 보안 결정은 자주 간과되는 문제 중 하나입니다. 개발과정에서 도메인 이름을 기반으로 인증, 접근 제어 등 보안 결정을 내리는 것이 일반적인 관행이기 때문입니다.
이번 포스팅에서는 DNS lookup에 의존한 보안결정에 대해 알아보고 취약한 코드 예제와 이를 방지하기 위한 안전한 코드 작성 방법을 살펴보려고 합니다.
DNS lookup에 의존한 보안결정 이란?
소프트웨어 개발에서 DNS lookup은 네트워크 통신에 필수적입니다. 이를 통해 도메인 이름을 IP 주소로 변환하여 통신을 수행합니다. DNS lookup에 의존한 보안 결정은 도메인 이름을 기반으로 보안 결정을 내리는 것을 의미합니다. 하지만 DNS lookup에 의존하는 보안 결정은 예상치 못한 문제를 야기할 수 있습니다. 예를 들어, 악의적인 DNS 서버를 통해 중요한 정보를 빼내거나, 사용자를 다른 사이트로 리다이렉션할 수 있습니다.
공격 메커니즘
DNS lookup에 의존한 보안 결정은 다음과 같은 공격에 취약합니다.
- DNS 스푸핑 : 공격자는 DNS 요청에 대한 위조된 응답을 보내어 사용자들을 속이는 것을 목표로 합니다. 이를 통해 공격자는 사용자의 트래픽을 가로채거나 중간에서 정보를 탈취할 수 있습니다.
- DNS 캐시 포이즈닝 : 공격자는 DNS 서버의 캐시를 변조하여 특정 도메인과 매핑된 IP를 조작합니다. 이를 통해 사용자를 악성 사이트로 리다이렉션 할 수 있습니다.
- 중간자 공격 : 공격자는 DNS 트래픽을 가로채어 중간에서 조작하는 것을 목표로 합니다. 이를 통해 공격자는 사용자와 목적지 사이에 위치하여 통신을 조작하고 정보를 탈취할 수 있습니다.
- 이렇게 다양한 공격은 DNS lookup에 의존하여 네트워크 통신을 수행하는 애플리케이션에 영향을 미칩니다. 따라서 DNS 보안 결정을 내릴 때 이러한 공격 메커니즘을 고려하여 안전한 방법으로 네트워크 통신을 구축하는 것이 중요합니다.
취약한 웹 애플리케이션의 예
public static void main(String[] args) {
1 String domainName = "example.com";
2 InetAddress ipAddress = InetAddress.getByName(domainName);
System.out.println("IP Address for " + domainName + ": " + ipAddress);
}
- 1 : DNS lookup을 수행할 도메인 이름을 예시를 위하여 지정하였습니다.
- 2 : example.com 도메인 이름에 대한 IP 주소를 가져옵니다. 이 과정이 DNS lookup 과정입니다. 이 조회 과정에서 중간자 공격이나 DNS 캐시 독점과 같은 공격에 취약합니다. 공격자가 DNS 응답을 가로채거나 변조하여 악성 IP 주소를 반환하면, 사용자는 해당 IP 주소로 리다이렉션 될 수 있습니다.
시큐어코딩 적용 방법
public static void main(String[] args) {
1 String domainName = "example.com";
2 String dnsServer = "8.8.8.8"; //Public DNS
try {
InetAddress ipAddress = InetAddress.getByName(domainName);
System.out.println("IP : " + ipAddress);
3 } catch (UnknownHostException e) {
try {
5 InetAddress ipAddress = InetAddress.getByName(domainName, InetAddress.getByName(dnsServer));
System.out.println("IP : " + ipAddress);
6 } catch (UnknownHostException ex) {
System.err.println("Unable to find IP address for " + domainName);
ex.printStackTrace();
}
}
}
- 1 : DNS lookup을 수행할 도메인 이름을 예시를 위하여 지정하였습니다.
- 2 : 안전한 DNS 서버로 사용할 IP 주소를 지정합니다.(8.8.8.8은 구글입니다.)
- 3, 6 : UnkownHostException 예외를 발생시킵니다. 이는 잘못된 호스트 이름, 네트워크 연결 문제, DNS 서버 문제가 발생하는 경우 발생합니다.
- 5 : 안전한 DNS를 사용하여 도메인 이름에 대한 IP 주소를 가져옵니다.
- 안전한 Public DNS를 사용하여 조회를 하면 기존 DNS 서버로부터 IP 주소를 가져오는 것에 실패할 경우, 안전한 DNS 서버를 이용해 안전하게 DNS를 조회를 할 수 있고, 안전한 DNS 서버로 알려져 있기 때문에 DNS 포이즈닝이나 DNS 스푸핑과 같은 공격으로부터 보호할 수 있습니다.
DNS lookup에 의존한 보안결정을 방지하기 위한 방법은 다음과 같은 방법들도 있습니다.
- IP 주소를 직접 사용 : DNS lookup을 피하기 위해 목적지 서버의 IP 주소를 직접 사용할 수 있습니다. 다만, 이 방법은 IP 주소가 변경될 경우 코드를 계속 수정하기에 유지 보수에 어려움을 줄 수 있습니다.
- DNNSEC : DNSSEC은 DNS 데이터의 무결성을 보호하기 위한 보안 프로토콜입니다. DNSSEC을 활용하면 DNS 데이터가 조작되지 않았음을 검증할 수 있습니다.
- SSL/TLS : SSL 또는 TLS를 사용하여 네트워크 통신을 암호화할 수 있습니다. 이를 통해 중간자 공격과 같은 위협으로부터 데이터를 보호할 수 있습니다.