NGINX를 사용한 HTTPoxy 취약점 완화

NGINX | 2016년 7월 18일

2016년 7월 18일, ‘HTTPoxy’라는 취약점이 공개되었습니다. 이 취약점은 일부 FastCGI 구성과 같은 CGI 또는 CGI 유사 환경에서 실행되는 일부 서버 측 웹 애플리케이션에 영향을 미칩니다. 현재까지 영향을 받는 것으로 알려진 언어로는 PHP, Python, Go가 있습니다.

특정 언어 및 CGI 구현과 관련하여 여러 CVE가 할당되었습니다:

이 취약점을 설명하는 새로운 웹사이트와 CERT 취약점 공지, 그리고 취약점 발견 과정에 대한 설명이 있습니다. Vend의 오픈 소스 웹 개발자인 Dominic Scheirlinck의 개인 웹사이트에서도 추가 정보를 확인할 수 있습니다.

이 게시물에서는 해당 취약점을 설명하고, NGINX 또는 NGINX Plus를 사용하여 서버에서 이 취약점을 악용하려는 시도를 차단하는 방법을 안내합니다.

이 취약점은 네임스페이스 충돌로 인해 발생합니다. CGI 또는 FastCGI와 유사한 인터페이스는 HTTP 요청 매개변수를 기반으로 환경 변수를 설정하며, 이 환경 변수가 애플리케이션 구성에 사용되는 내부 변수를 재정의할 수 있습니다.

현재 알려진 이 취약점의 유일한 악용 사례는 특정 HTTP 클라이언트 라이브러리를 사용하여 다른 서비스에 HTTP 요청을 보내는 CGI 및 CGI 유사 환경에서 실행되는 웹 애플리케이션을 대상으로 합니다. 이 경우 공격자는 애플리케이션에서 생성된 내부 요청을 자신이 선택한 서버로 리디렉션하여 아래와 같이 요청에 포함된 모든 비밀 데이터를 탈취할 수 있습니다.

HTTPoxy는 네임스페이스 중복을 이용해 내부 서버 트래픽에 접근합니다

NGINX 또는 NGINX Plus를 사용하여 이 취약점을 악용하려는 시도를 식별하고 차단할 수 있습니다. 이를 통해 공격을 효과적으로 방지하고, 영향을 받는 코드를 감사하고 업데이트할 시간을 확보할 수 있습니다.

HTTPoxy 취약점이 악용되는 방식

이 취약점의 작동 방식과 이로부터 사이트를 보호하는 방법을 이해하려면 CGI 및 CGI와 유사한 인터페이스가 환경 변수를 설정하는 방식과 일부 애플리케이션 라이브러리가 환경 변수로 구성되는 방식을 알아야 합니다.

1 – CGI 및 CGI 유사 인터페이스는 HTTP_*라는 이름의 환경 변수를 정의합니다

많은 웹 애플리케이션 플랫폼은 애플리케이션을 웹 서버에 연결하기 위해 CGI 또는 CGI와 유사한 인터페이스를 사용합니다. 이러한 인터페이스는 HTTP 요청의 헤더를 접두사가 HTTP_인 환경 변수로 변환합니다. 그러면 애플리케이션은 환경을 검사하여 요청 헤더(예: User-Agent)의 값을 조회할 수 있습니다.

클라이언트는 적절한 헤더가 포함된 요청을 전송하여 애플리케이션 환경에 임의의 환경 변수(HTTP_)를 생성할 수 있습니다. 예를 들어 요청 헤더 Foo: bar는 환경 변수 HTTP_FOO=bar로 변환됩니다.

일부 플랫폼은 PHP의 $_SERVER 전역 변수처럼 환경 변수를 숨기는 추상화 계층을 제공합니다. 하지만 이러한 추상화는 환경 변수를 설정하는 표준 CGI 및 FastCGI 방식을 기반으로 구현됩니다.

예를 들어 FastCGI 모드에서 실행되는 PHP 애플리케이션은 다음과 같이 요청의 User-Agent 헤더를 확인할 수 있습니다:

// both methods return the same result$useragent = getenv( 'HTTP_USER_AGENT' );
$useragent = $_SERVER['HTTP_USER_AGENT'];

2 – 일부 애플리케이션 라이브러리는 환경 변수를 통해 구성됩니다

복잡한 웹 애플리케이션은 외부 라이브러리에서 기능을 가져옵니다. 예를 들어 애플리케이션이 다른 서비스에 HTTP 요청을 보내야 하는 경우가 있는데(마이크로서비스와 유사한 방식), 이를 위해 널리 사용되는 서드 파티 라이브러리 중 하나를 사용할 수 있습니다. 이러한 라이브러리는 흔히 HTTP 프록시라는 기능을 지원하는데, 이는 HTTP 요청을 중계하는 데 사용되는 중간 서버입니다.

이와 같은 라이브러리를 손쉽게 구성하는 방법 중 하나는 환경 변수를 통해 설정을 정의하는 것입니다. 널리 사용되는 PHP Guzzle 라이브러리는 일부 설정에 HTTP_PROXY라는 환경 변수를 사용하며, 이 변수에는 프록시 서버의 주소가 지정됩니다. HTTP_PROXY를 이와 같이 설정하면 라이브러리에서 생성하는 모든 HTTP 요청이 프록시 서버 주소를 통해 전달됩니다. Go의 net/http 패키지와 Python의 Requests 모듈도 HTTP_PROXY 환경 변수를 동일한 방식으로 신뢰하고 해석합니다.

3 – 취약점의 특성

항목 2에서 설명한 라이브러리는 CGI 또는 CGI와 유사한 인터페이스를 염두에 두고 설계되지 않았으며, 이 라이브러리가 신뢰하는 HTTP_PROXY 환경 변수는 항목 1에서 설명한 대로 CGI 및 FastCGI 인터페이스에서 사용하는 HTTP_ 네임스페이스와 겹칩니다.

공격자는 HTTP_PROXY 환경 변수의 값을 자신이 선택한 주소로 설정하여 애플리케이션에서 생성된 내부 HTTP 요청을 리디렉션하고 가로챌 수 있습니다. 이러한 요청에는 인증 키 및 비공개 데이터와 같은 민감한 정보가 포함될 수 있으며, 악용 가능한 추가 API 및 엔드포인트에 관한 정보가 노출될 수도 있습니다.

공격자는 Proxy 헤더가 포함된 요청을 전송하여 이를 수행할 수 있으며, CGI 또는 FastCGI 인터페이스는 해당 애플리케이션 호출에 대해 HTTP_PROXY라는 환경 변수를 그대로 생성합니다. 이 허위 Proxy 헤더가 포함된 요청만 직접적인 영향을 받는다는 점에 유의하세요.

NGINX 및 NGINX Plus를 사용하여 공격 차단하기

HTTPoxy 취약점은 NGINX에 직접적인 영향을 미치지는 않지만, NGINX와 NGINX Plus를 사용하여 이 취약점을 악용한 공격을 차단할 수 있습니다.

업스트림 FastCGI 애플리케이션과 통신하기

NGINX를 사용하여 HTTP_PROXY FastCGI 매개변수를 빈 문자열로 설정하면 애플리케이션에 전달되는 입력을 “정제”할 수 있습니다. 이렇게 하면 FastCGI 요청에서 해당 매개변수가 완전히 제거됩니다:

fastcgi_param HTTP_PROXY "";

HTTP 트래픽 로드 밸런싱 및 프록시 처리

HTTP 요청을 업스트림 애플리케이션으로 프록시할 때는 업스트림 애플리케이션이 취약한 플랫폼에서 실행 중일 가능성에 대비해 모든 Proxy 헤더를 빈 문자열로 설정하는 것이 좋습니다:

proxy_set_header Proxy "";

취약점 악용 시도 탐지

Proxy는 표준 HTTP 헤더가 아니므로 이 헤더가 포함된 모든 요청은 의심스러운 요청으로 간주할 수 있습니다. NGINX 또는 NGINX Plus를 사용하여 이러한 의심스러운 요청을 전용 액세스 로그에 기록할 수 있습니다. 여기서는 이 로그의 이름을 badactor.log로 지정합니다:

# define 'proxylog' format in the http{} context:log_format proxylog '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_proxy"';

# log requests with a Proxy header using the 'proxylog' format
access_log /var/log/nginx/badactor.log proxylog if=$http_proxy;

참고: 이 access_log 지시어를 배치한 구성 컨텍스트에서는 NGINX 구성의 상위 수준에 정의된 모든 액세스 로깅 설정을 재정의합니다.

안전 유지

NGINX와 NGINX Plus는 HTTPoxy 공격을 모니터링하고 차단하는 효과적인 방법을 제공합니다. 취약점을 제거하기 위해 코드를 감사하고 업데이트하고 테스트하는 동안 위에서 설명한 기법을 사용하여 애플리케이션을 보호하세요.

궁금한 점이 있으면 이 게시물에 댓글을 남겨 주세요. NGINX Plus 구독자라면 언제든지 지원팀에 문의하여 도움을 받으세요.


공유

작성자 소개

관련 블로그 게시물

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
NGINX | 2023. 11. 30.

시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric

이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
NGINX | 2023. 03. 23.

F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법

앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
NGINX | 2021. 09. 27.

Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션

개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX | 2021. 07. 06.

진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법

NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX | 2021. 06. 30.

NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리

NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
NGINX | 2015. 03. 25.

Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유

Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.