HTTPoxy 취약점 NGINX로 완화하기

일부 FastCGI 구성과 같이 CGI 또는 CGI와 유사한 환경에서 실행되는 일부 서버 측 웹 애플리케이션에 영향을 미치는 HTTPoxy 라는 취약점이 발표되었습니다. 현재까지 영향을 받는 것으로 알려진 언어로는 PHP, Python, Go 등이 있습니다.

특정 언어와 CGI 구현을 다루는 여러 CVE가 지정되었습니다.

Apache HTTP Server (CVE-2016-5387)

Apache Tomcat (CVE-2016-5388)

Go (CVE-2016-5386)

PHP (CVE-2016-5385)

취약점을 설명하는 새로운 웹 사이트, CERT 취약점 노트취약점 발견에 대한 설명이 있습니다. Vend의 Open Source 웹 개발자인 Dominic Scheirlinck의 개인 웹사이트에 추가 정보가 있습니다.

이 포스트에서는 이 취약점에 대해 설명하고 서버에서 이 취약점을 악용하려는 시도를 무력화하기 위해 NGINX 또는 NGINX Plus를 사용하는 방법을 설명합니다.

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

현재 알려진 이 취약점의 유일한 악용 사례는 특정 HTTP 클라이언트 라이브러리를 사용하여 다른 서비스에 HTTP 요청을 하는 CGI 및 CGI 유사 환경에서 실행되는 웹 애플리케이션입니다. 이 경우 공격자는 아래 그림과 같이 애플리케이션에서 생성된 내부 요청을 원하는 서버로 리다렉션하여 요청에 포함된 모든 Secret 데이터를 캡처할 수 있습니다.

Defeating HTTPoxy with NGINX and NGINX Plus

HTTPoxy 는 Namespace 중첩을 사용하여 내부 서버 트래픽에 액세스합니다.

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

목차

1. HTTPoxy 취약점이 악용되는 방법
1-1. CGI 및 CGI 유사 인터페이스는 HTTP_*라는 이름의 환경 변수를 정의합니다.
1-2. 일부 애플리케이션 라이브러리는 환경 변수를 통해 구성됩니다.
1-3. 취약점의 특성
2. NGINX 및 NGINX Plus를 사용하여 공격 방어하기
2-1. Upstream FastCGI 애플리케이션과 통신하기
2-2. Load Balancing 및 HTTP 트래픽 Proxy 처리
2-3. 취약점을 악용하려는 시도 탐지하기
3. HTTPoxy 결론

1. HTTPoxy 취약점이 악용되는 방법

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

1-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'];

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

복잡한 웹 애플리케이션은 외부 라이브러리에서 기능을 가져옵니다. 예를 들어, 애플리케이션이 Microservices와 같은 방식으로 다른 서비스에 HTTP 요청을 해야 하는 경우가 있는데, 이때 일반적인 타사 라이브러리 중 하나를 사용할 수 있습니다. 이러한 라이브러리는 HTTP 요청을 중계하는 데 사용되는 중개 서버인 HTTP Proxy라는 기능을 지원하는 경우가 많습니다.

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

1-3. 취약점의 특성

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

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

공격자는 Proxy 헤더가 포함된 요청을 보내면 CGI 또는 FastCGI 인터페이스가 해당 애플리케이션 호출을 위해 HTTP_PROXY라는 환경 변수를 순순히 생성합니다. 가짜 Proxy 헤더가 포함된 요청만 직접 영향을 받습니다.

2. NGINX 및 NGINX Plus를 사용하여 공격 방어하기

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

2-1. Upstream FastCGI 애플리케이션과 통신하기

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

fastcgi_param HTTP_PROXY "";

2-2. Load Balancing 및 HTTP 트래픽 Proxy 처리

HTTP 요청을 Upstream 애플리케이션으로 Proxy 할 때는 Upstream 애플리케이션이 취약한 플랫폼에서 실행되는 경우 Proxy 헤더를 빈 문자열로 설정하는 것이 좋습니다:

proxy_set_header Proxy "";

2-3.HTTPoxy 취약점을 악용하려는 시도 탐지하기

Proxy는 표준 HTTP 헤더가 아니므로 이 헤더가 포함된 모든 요청은 의심스러운 것으로 간주할 수 있습니다. NGINX 또는 NGINX Plus를 사용하여 이러한 의심스러운 요청을 전용 Access Log(여기서는 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;

Note: 이 access_log 지시문을 배치하는 구성 컨텍스트에서 이 지시문은 NGINX 구성의 상위 수준에서 정의된 모든 Access Log를 재정의합니다.

3. HTTPoxy 결론

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

NGINX Plus를 직접 사용해 보거나 테스트해 보려면 지금 30일 무료 평가판을 신청하거나 사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.