보안정보
전문화된 보안 관련 자료, 보안 트렌드를 엿볼 수 있는
차세대 통합보안관리 기업 이글루코퍼레이션 보안정보입니다.
HTTP Request Smuggling 취약점의 발생 원리와 대응 방안
2024.11.15
509
01. HTTP Request Smuggling 취약점 개요
2005년 발견된 HTTP Request Smuggling은 다양한 웹 서버와 프록시 서버 구성 상의 차이로 인해 발생하는 취약점이다. Content-Length와 Transfer-Encoding Header의 모호성을 악용해서 다수의 사용자로부터 수신된 HTTP Request를 처리하는 것을 방해해서 민감한 데이터에 무단 접근하거나 다른 어플리케이션 사용자를 공격할 수 있다.
Front-end가 Content-Length Header를 우선시하는 반면, Back-end는 Transfer-Encoding 헤더를 우선시하는 경우 Front-end 서버와 Back-end 서버 간의 불일치를 이용해 추가적인 Request를 삽입할 수 있게 된다.
HTTP Request Smuggling은 HTTP/1.1 프로토콜의 설계와 구현의 차이를 이용하기 때문에 로드 밸런서, 프록시, 캐시 서버 등과 같은 중간의 경유 서버에서 주로 발생되기 때문에 대규모 사용자 요청을 처리하는 환경일수록 공격의 영향도가 높다. 일반적으로 HTTP/1.1에서 발생하지만 HTTP/2를 지원하는 웹 사이트도 Back-end의 아키텍처에 따라서 공격에 취약할 수 있다.
HTTP Request Smuggling은 웹 애플리케이션 보안에서 매우 중요한 취약점 중 하나이다. 이 취약점은 웹 서버 또는 프록시 서버가 HTTP 요청을 처리하는 방식의 차이를 악용하여 발생한다. 공격자는 이를 통해 서버 간의 요청을 의도적으로 잘못 해석하게 만들고 이를 통해 권한 상승(Privilege Escalation), 세션 하이재킹(Session Hijacking), 민감한 정보 노출(Critical Info Leak) 등의 심각한 보안 문제를 유발할 수 있다. 따라서 이번 호에서는 HTTP Request Smuggling이 발생하는 원인과 이를 대응하기 위한 다양한 방안에 대해서 제시해보고자 한다.
02. HTTP Request Smuggling 발생 배경과 원리
1) 정상적인 요청 처리
[그림 1]은 정상적인 요청 처리를 나타낸다. 여러 사용자가 웹 서버에 HTTP 요청을 보낼 때 Front-end 서버는 요청을 올바르게 수신한 다음 Back-end 서버로 전달한다.
1.사용자가 Front-end 서버에 HTTP Request를 보낸다.
2.Front-end 서버는 HTTP Request를 받아서 올바르게 Back-end 서버에 전달한다.
3.Back-end 서버는 Front-end 서버에서 받은 Request를 순차적으로 처리 후 정상적인 Response를 반환한다.
4.최종적으로 Front-end 서버는 Back-end 서버의 Response을 사용자에게 반환한다.
2) 공격자가 개입한 요청 처리
[그림 2]는 공격자가 개입하여 HTTP Request Smuggling을 수행하는 상황을 나타낸다. 공격자는 정상적인 요청 사이에 악의적인 요청을 삽입하여 서버 간의 요청 처리 방식을 혼란스럽게 만든다.
1.공격자가 Front-end 서버에 악의적인 HTTP 요청을 보낸다. 이 요청에는 Content-Length 헤더와 Transfer-Encoding 헤더 간의 모호성을 이용한 악의적인 페이로드가 포함된다.
2.Front-end 서버는 이 요청을 정상적인 요청으로 간주하고 Back-end 서버에 전달한다.
3.Back-end 서버는 Front-end 서버에서 전달된 요청을 다르게 해석하며, 악의적인 요청을 포함한 전체 데이터를 처리한다.
4.최종적으로 공격자는 다른 사용자의 요청을 가로채거나 세션 하이재킹 등의 공격을 수행할 수 있게 된다.
03. HTTP Request 헤더와 불일치
HTTP 요청 처리의 불일치는 다양한 서버들이 HTTP 요청을 다르게 해석할 때 발생한다. Content-Length와 Transfer-Encoding 헤더 간의 우선순위 차이, HTTP 표준에 대한 해석 차이 등이 이러한 불일치를 발생시킨다. HTTP Request Smuggling 공격은 이를 악용하여 서버 간의 요청 경계를 흐려 악의적인 요청을 삽입하고 다양한 악의적인 행위를 수행할 수 있다.
1) Content-Length
Content-Length는 HTTP Request의 Body 길이를 바이트 단위로 명시하며 메시지 본문의 정확한 크기를 알려줌으로써 메시지의 끝을 명확하게 정의한다. 만약 Content-Length가 실제 본문 길이와 다를 경우 다음과 같은 문제가 발생할 수 있다.
① Content-Length 헤더 값이 실제 본문 길이보다 작은 경우
서버나 프록시는 설정된 Content-Length 값에 도달하면 메시지의 끝으로 인식하고 그 이후의 데이터는 무시하거나 다음 요청의 일부로 잘못 처리한다. 이는 데이터 손실로 이어지며 HTTP 응답이 잘려서 클라이언트에 전달된다. 서버 A와 서버 B가 Front-end와 Back-end 서버로 연결되어 있으며 클라이언트가 다음과 같은 요청을 보낸다.
서버 A는 Content-Length 헤더를 5로 인식하고 'IGLOO'를 수신한 후 메시지의 끝으로 처리한 다음, 나머지 'GET /admin HTTP/1.1'을 다음 요청으로 인식하게 된다. 이는 서버 B에서 처리되어 민감한 admin 페이지에 접근하게 되는 상황을 초래할 수 있다. 이로 인해 공격자는 인증 없이 관리자 페이지에 접근하여 중요한 정보를 노출하거나 변경할 수 있는 보안 취약점이 발생하게 된다.
② Content-Length 헤더 값이 실제 본문 길이보다 큰 경우
서버나 프록시는 설정된 Content-Length 값만큼 데이터를 기다린다. 클라이언트가 보내는 본문의 길이가 Content-Length 헤더에 명시된 길이보다 짧을 경우 서버는 나머지 데이터를 기다리게 된다. 이때 클라이언트가 추가 데이터를 보내지 않으면 서버는 연결이 끊어질 때까지 대기하거나 설정된 타임아웃이 지나기 전까지 대기하게 된다. 이러한 경우 Front-end 서버는 데이터를 기다리게 되고 다음 요청을 잘못된 방식으로 처리할 수 있으며 이로 인해 공격자가 악의적인 데이터를 추가로 전송할 수 있는 기회가 생길 수 있다. 서버 A와 서버 B가 Front-end와 Back-end 서버로 연결되어 있으며 클라이언트가 다음과 같은 요청을 보낸다.
서버 A는 설정된 Content-Length 값인 20바이트를 기다린다. 클라이언트가 5바이트의 데이터(IGLOO)만 전송하고 연결을 종료하면 Front-end 서버는 나머지 데이터를 기다리게 된다. 이는 연결의 타임아웃을 초래하거나 잘못된 요청으로 처리될 수 있으며 Front-end 서버는 이 데이터를 부분적으로 처리하게 되며 이로 인해 클라이언트는 추가 데이터를 전송할 수 있는 기회를 얻고, 악의적인 요청을 이어서 보낼 수 있게 된다.
2) Transfer-Encoding
Chunked Transfer-Encoding은 HTTP/1.1에서 사용되며 데이터를 여러 개의 청크(chunk)로 나누어 전송하는 방식이다. 각 청크는 그 크기를 나타내는 헤더로 시작하며 마지막 청크는 '0\r\n\r\n'으로 표시된다. Chunked Transfer-Encoding을 사용하면 클라이언트가 전체 메시지 크기를 알 필요 없이 데이터를 전송할 수 있다.
[그림 5]에서 데이터는 'IGLOO'로 구성된 하나의 청크로 나뉘어 전송된다. 첫 번째 줄(5\r\n
)은 청크의 크기(5)를 나타내고 마지막 줄(0\r\n\r\n)은 더 이상의 데이터가 없음을 나타낸다.
3) HTTP 요청 처리 불일치의 발생 원인
HTTP 요청 처리의 불일치는 서로 다른 서버나 프록시가 HTTP 요청을 해석하고 처리하는 방식의 차이로 인해 발생한다. 이러한 불일치가 발생하는 구체적인 이유는 아래와 같다.
04. HTTP Request Smuggling 취약점의 주요 유형
HTTP Request Smuggling 취약점은 주로 세 가지 주요 유형으로 나눠진다. 이는 Front-end 서버와 Back-end 서버 사이의 HTTP 헤더 처리 방식의 차이를 기반으로 분류된다. 각 유형은 Content-Length 헤더와 Transfer-Encoding 헤더의 처리 방식에 따라 다르며 이로 인해 HTTP 요청의 불일치가 발생하는 방식을 다르게 해석한다.
1) CL.TE (Content-Length to Transfer-Encoding)
CL.TE는 Front-end 서버가 Content-Length를 기준으로 요청을 해석하고 Back-end 서버가 Transfer-Encoding: chunked를 기준으로 해석하는 경우 발생한다. 이 경우, Front-end 서버는 ‘Content-Length’ 헤더를 사용하여 요청 본문을 처리한 다음, 나머지 데이터를 Back-end 서버로 전달한다. Back-end 서버는 전달된 데이터를 ‘Transfer-Encoding: chunked’ 헤더를 사용하여 여러 청크로 나누어 처리하게 된다. 결과적으로 공격자는 요청에 악의적인 데이터를 포함시켜 Back-end 서버에서 예상치 못한 추가 요청을 실행시킬 수 있다.
[그림 6]의 요청에서 Front-end 서버는 Content-Length 헤더를 우선적으로 처리하여 Content-Length: 6에 해당하는 데이터를 읽어들인다. 그러나 Transfer-Encoding: chunked 헤더도 존재하므로 이후에 청크된 데이터가 올 것이라고 인식한다. Front-end 서버는 0 청크를 통해 데이터 전송이 종료되었음을 확인하고 이후 데이터를 Back-end 서버로 전달한다.
반면 Back-end 서버는 Transfer-Encoding: chunked 헤더를 무시하고 Content-Length: 6만을 처리하여 첫 6바이트만 읽고 나머지 데이터를 다음 요청의 일부로 해석한다. 따라서 Back-end 서버는 '0\r\n\r\nG'를 첫 요청의 일부로 처리하고 'POST / HTTP/1.1\r\nHost: iglootest01.com\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 7\r\n\r\nfoo=bar' 등의 나머지 데이터를 다음 요청의 일부로 잘못 해석하게 된다.
이후, 정상적인 요청을 전송하게 되면 Front-end 서버는 Content-Length: 7 헤더를 사용하여 요청을 처리하고 전체 데이터를 Back-end 서버로 전달한다. 하지만 Back-end 서버는 앞서 공격 요청에서 남겨진 데이터를 이번 정상 요청의 일부로 인식하여 요청을 GPOST / HTTP/1.1로 처리한다.
이로 인해 Back-end 서버는 인식할 수 없는 메서드 GPOST로 요청을 잘못 처리하게 되며 ‘403 Forbidden’ 상태 코드와 'Unrecognized method GPOST' 메시지를 반환한다. 이 응답은 CL.TE 공격이 성공했음을 알 수 있으며 Front-end와 Back-end 서버 간의 요청 해석 차이를 통해 공격자가 의도한 대로 서버가 잘못된 요청을 처리하게 된다는 것을 나타낸다.
2) TE.CL (Transfer-Encoding to Content-Length)
TE.CL 취약점은 HTTP 요청 헤더에 ‘Transfer-Encoding’과 ‘Content-Length’ 헤더가 동시에 존재할 때 발생하는 취약점이다. 이 취약점은 Front-end 서버와 Back-end 서버가 각각 다른 헤더를 우선적으로 해석하는 상황에서 발생한다. 즉, Front-end 서버는 Transfer-Encoding 헤더를 우선적으로 처리하고 Back-end 서버는 Content-Length 헤더를 우선적으로 처리한다. 이를 통해 공격자는 의도한 대로 HTTP 요청을 조작할 수 있다.
[그림 8]의 요청에서 Front-end 서버는 첫 번째 Transfer-Encoding: chunked 헤더를 처리하여 첫 번째 청크(56\r\n)를 인식하고 56 바이트의 데이터를 읽어들인다. 이 데이터를 Back-end 서버로 전달하며, 두 번째 청크(0\r\n)를 통해 데이터 전송이 종료되었음을 확인한다. 반면, Back-end 서버는 Transfer-Encoding: chunked 헤더를 무시하고 Content-Length: 4를 우선적으로 처리하여 첫 4바이트만 읽고 나머지 데이터를 다음 요청의 일부로 해석한다. 따라서 Back-end 서버는 'GPOS'를 첫 요청의 일부로 처리하고, 'T HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 6\r\n\r\n0\r\n\r\n' 등의 나머지 데이터를 다음 요청의 일부로 잘못 해석하게 된다.
이후, 정상적인 요청을 전송하게 되면 Front-end 서버는 Content-Length: 7 헤더를 사용하여 요청을 처리하고 전체 데이터를 Back-end 서버로 전달한다. 하지만 Back-end 서버는 앞서 공격 요청에서 남겨진 데이터를 이번 정상 요청의 일부로 인식하여 요청을 GPOST / HTTP/1.1로 처리한다.
이로 인해 Back-end 서버는 인식할 수 없는 메서드 GPOST로 요청을 잘못 처리하게 되며 ‘403 Forbidden’ 상태 코드와 'Unrecognized method GPOST' 메시지를 반환한다. 이 응답은 TE.CL 공격이 성공했음을 알 수 있으며 Front-end와 Back-end 서버 간의 요청 해석 차이를 통해 공격자가 의도한 대로 서버가 잘못된 요청을 처리하게 된다는 것을 나타낸다.
3) TE.TE (Transfer-Encoding to Transfer-Encoding)
TE.TE 취약점은 HTTP 요청 헤더에 ‘Transfer-Encoding’ 헤더가 중복되어 사용될 때 발생한다. 이 취약점은 Front-end 서버와 Back-end 서버 간의 요청 해석 차이로 발생할 수 있는 취약점이다. 이 취약점을 통해 공격자는 의도하지 않은 방식으로 서버가 요청을 해석하도록 할 수 있다.
[그림 10]의 요청에서 Front-end 서버는 첫 번째 Transfer-Encoding: chunked 헤더를 처리하여 첫 번째 청크(5c\r\n)를 인식하고 92 바이트의 데이터를 읽어들인다. 이 데이터를 Back-end 서버로 전달하며 두 번째 청크(0\r\n)를 통해 데이터 전송이 종료되었음을 확인한다. 반면, Back-end 서버는 Transfer-Encoding: foobar 헤더를 무시하고 Content-Length: 4를 우선적으로 처리하여 첫 4바이트만 처리하고 나머지 데이터를 다음 요청의 일부로 해석한다.
따라서 Back-end 서버는 'GPOS'를 첫 요청의 일부로 처리하고 'T / HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 11\r\n\r\nx=1\r\n0\r\n\r\n' 등의 나머지 데이터를 다음 요청의 일부로 잘못 해석하게 된다.
이후, 정상적인 요청을 전송하게 되면 Front-end 서버는 Content-Length: 7 헤더를 사용하여 요청을 처리하고 전체 데이터를 Back-end 서버로 전달한다. 하지만 Back-end 서버는 앞서 공격 요청에서 남겨진 데이터를 이번 정상 요청의 일부로 인식하여 요청을 GPOST / HTTP/1.1로 처리한다.
이로 인해 Back-end 서버는 인식할 수 없는 메서드 GPOST로 요청을 잘못 처리하게 되며 ‘403 Forbidden’ 상태 코드와 'Unrecognized method GPOST' 메시지를 반환한다. 이 응답은 TE.TE 공격이 성공했음을 알 수 있으며 Front-end와 Back-end 서버 간의 요청 해석 차이를 통해 공격자가 의도한 대로 서버가 잘못된 요청을 처리하게 된다는 것을 나타낸다.
05. HTTP Request Smuggling 탐지 방법
HTTP Request Smuggling 공격을 탐지하기 위해서는 의도적으로 잘못된 요청을 보내서 서버의 반응을 관찰하는 방법이 있다. 특히 Content-Length와 Transfer-Encoding 헤더를 조작하여 서버의 반응을 확인함으로써 취약성을 탐지할 수 있다.
이를 통해 서버가 의심스러운 요청을 처리할 때 발생하는 딜레이를 확인할 수 있다. 이 방법을 사용하면 서버가 Transfer-Encoding 헤더를 어떻게 처리하는지, 특히 Back-end 서버가 Transfer-Encoding을 신뢰하는지 여부를 확인할 수 있으며, 이를 통해 HTTP Request Smuggling 공격에 대한 취약성을 판단할 수 있다. 먼저 [그림 12]는 정상적인 요청을 보여준다.
Front-end 서버는 청크 인코딩을 처리하여 이를 Back-end 서버로 전달한다. Back-end 서버는 Content-Length 헤더를 사용하여 본문의 길이를 6바이트로 해석하고 청크가 올바르게 종료된 것을 확인한 후 데이터를 정상적으로 처리한다.이러한 정상적인 요청에 대한 응답으로 Back-end 서버는 상태 코드 200 OK와 함께 HTML 문서를 반환한다. 이 응답은 요청이 성공적으로 처리되었음을 나타낸다.
1) CL.TE 취약점 탐지
[그림 13]의 요청에서 Front-end 서버는 Content-Length 헤더를 사용하여 본문의 길이를 6바이트로 해석하고 abc까지만 처리하며 나머지 x는 무시한다. 반면, Back-end 서버는 Transfer-Encoding 헤더를 사용하여 청크 인코딩을 처리하고 첫 번째 청크 3\r\nabc\r\n를 처리한 후 다음 청크를 기다리게 된다. 하지만 다음 청크가 도착하지 않기 때문에 Back-end 서버는 타임아웃이 발생하여 ‘500 Internal Server Error’와 ‘Server Error: Communication timed out’ 응답을 반환한다. 이는 서버 간의 헤더 처리 차이를 이용한 Request Smuggling 취약점을 탐지하는 방법으로 응답이 지연되거나 타임아웃이 발생하면 취약점이 존재할 가능성이 높다는 것을 나타낸다.
2) TE. CL 취약점 탐지
[그림 14]의 요청에서 Front-end 서버는 Transfer-Encoding 헤더를 사용하여 청크 인코딩을 처리하고 3\r\nabc\r\n까지를 Back-end 서버로 전달하고 x는 다음 요청의 일부로 취급한다. 그러나 Back-end 서버는 Content-Length 헤더를 사용하여 요청 본문의 길이를 6바이트로 해석하고 abcx를 처리하려고 시도한다. 이로 인해 요청을 올바르게 처리하지 못하고 ‘400 Bad Request’와 ‘Invalid Request’ 응답을 반환하게 된다.
[그림 15]의 요청에서 Front-end 서버는 Transfer-Encoding 헤더를 사용하여 청크 인코딩을 처리하고 ‘0\r\n\r\n’을 청크 종료로 해석하여 이를 Back-end 서버로 전달한다. Back-end 서버는 Content-Length 헤더를 사용하여 본문의 길이를 6바이트로 해석하고 더 많은 데이터를 기대하지만 추가 데이터가 도착하지 않기 때문에 타임아웃이 발생하고 ‘500 Internal Server Error’와 ‘Server Error: Communication timed out’ 응답을 반환한다. 여기서 x는 무시되며 Back-end 서버는 데이터가 완전히 도착하지 않았다고 판단한다.
이 두 가지 요청을 통해 TE.CL(Request Smuggling) 취약점을 탐지할 수 있다. 첫 번째 요청은 비정상적인 요청이 서버 간의 헤더 처리 차이로 인해 올바르게 처리되지 않음을 확인하고, 두 번째 요청은 Back-end 서버가 추가 데이터를 기다리다 타임아웃이 발생하는지를 확인한다. 이러한 두 가지 접근 방식을 통해 TE.CL 취약점이 존재하는지를 더 확실하게 탐지할 수 있다. 응답이 지연되거나 타임아웃이 발생하면 TE.CL 취약점이 존재할 가능성이 높다는 것을 나타낸다.
06. HTTP Request Smuggling 취약점 대응방안
1) HTTP/2 End-to-End 사용 및 HTTP 다운그레이드 비활성화
HTTP/2는 요청 길이를 결정하는 강력한 메커니즘을 사용하지만 HTTP 다운그레이드를 통해 HTTP/1.1로 변환될 경우 요청 받을 공격에 대비할 필요가 있으므로 가급적이면 HTTP/2를 End-to-End로 사용하고 HTTP 다운그레이드를 비활성화해야 한다.
① Apache 설정 예
Apache의 경우, ‘mod_http2’ 모듈을 활성화 한 후 각 사이트의 설정 파일에 ‘Protocols h2 http/1.1’를 추가하여 HTTP/2를 활성화한다.
② Nginx 설정 예
Nginx의 경우, 기본적으로 HTTP/2를 지원하므로 각 사이트의 설정 파일에서 listen 지시자에 ‘http2’를 추가하여 HTTP/2를 활성화한다.
2) HTTP/1.1 다운그레이드 된 요청 검증
HTTP/2를 사용할 수 없을 경우 HTTP/1.1로 다운그레이드 된 요청이 발생할 수 있으며 이러한 요청은 HTTP Request Smuggling 공격의 대상이 될 수 있으므로 HTTP/1.1로 다운그레이드 된 요청을 철저히 검증하여 비정상적인 요청을 거부해야 한다.
① Apache 설정 예
Apache의 경우, 'mod_security2' 모듈을 설치하고 모듈의 설정 파일(modsecurity.conf) 내 비정상적인 요청을 감지하는 규칙을 추가할 수 있다. [그림 20]은 HTTP/1.1 요청에서 Transfer-Encoding: chunked와 Content-Length 헤더가 동시에 존재하는 경우를 감지하고 이러한 요청을 비정상적인 것으로 간주하여 400 상태 코드로 거부하고 헤더에 줄바꿈 문자가 포함된 요청, 헤더 이름에 콜론이 있는 요청, 요청 메서드에 공백이 있는 요청과 같이 HTTP/1.1 사양을 준수하지 않는 요청을 탐지하고 거부하는 규칙의 예이다.
② Nginx 설정 예
Nginx의 경우, 설정 파일(nginx.conf) 내 요청 검증 설정을 추가할 수 있다. [그림 22]는 HTTP/1.1 요청에서 Transfer-Encoding: chunked와 Content-Length 헤더가 동시에 존재하는 경우를 감지하고 이 요청을 비정상적인 것으로 간주하여 400 상태 코드로 거부하고 헤더 값에 줄바꿈 문자가 포함되거나 요청 메서드에 공백이 포함되어 있는 경우 해당 요청을 차단하는 설정의 예이다.
3) 요청 본문 존재 여부 가정하지 않기
요청에 본문이 없을 것이라고 가정할 경우 CL.0(Content-Length: 0)과 같은 헤더를 통해 클라이언트 측 비동기화 취약성이 발생할 수 있으므로 요청에 본문이 있을 가능성을 항상 고려하여 요청을 처리해야 한다. 아래의 설정들은 Content-Length 헤더가 비어 있을 경우(Content-Length가 존재하지 않으면) 해당 요청에 Content-Length를 0으로 설정하여 본문이 없음을 명확히 한다.
① Apache 설정 예
Apache의 경우 설정 파일(httpd.conf 또는 apache2.conf) 내 'mod_headers' 모듈을 사용하여 ‘RequestHeader’ 지시어를 통해 Content-Length 헤더가 존재하지 않는 경우, 해당 헤더를 0으로 설정할 수 있다. 이 설정을 통해 Apache 웹 서버는 요청에 Content-Length 헤더가 존재하지 않는 경우, 해당 헤더를 0으로 설정하여 본문이 없음을 명확히 할 수 있다.
② Nginx 설정 예
Nginx의 경우, 설정 파일(nginx.conf) 내 요청 검증 설정을 추가할 수 있다. [그림 24]는 location 블록 내에서 모든 요청에 대해 Content-Length 헤더가 존재하지 않는지 확인하고 존재하지 않는 경우 해당 헤더를 0으로 설정하는 방법의 예이다.
4) 서버 수준 예외 처리
요청을 처리하는 도중 서버 수준 예외가 발생하고 연결이 유지될 경우 보안 위협이 발생할 수 있으므로 요청을 처리할 때 서버 수준 예외가 발생하면 기본적으로 연결을 삭제하도록 설정해야 한다.
① Apache 설정 예
Apache의 경우, 설정 파일(httpd.conf 또는 apache2.conf) 내 'mod_security2' 모듈을 사용하여 요청을 처리하는 도중 서버 수준 예외가 발생하면 HTTP 500 상태 코드와 함께 연결을 종료하도록 설정할 수 있다.
② Nginx 설정 예
Nginx의 경우, 설정 파일(nginx.conf) 내 요청 검증 설정을 추가하여 요청을 처리하는 도중 서버 수준 예외가 발생할 때 기본적으로 연결을 종료하도록 설정할 수 있다.
5) 대응방안 적용 예시
① HTTP/2 설정 예
[그림 29]는 HTTP/2를 설정한 후 HTTP Request Smuggling 공격을 수행한 예시이다. HTTP/2는 요청을 프레임 단위로 처리하며 엄격한 규칙을 적용하여 비정상적인 요청을 감지하고 차단한다. Content-Length와 Transfer-Encoding: chunked를 동시에 사용하는 것은 명백한 규격 위반으로 간주되며, HTTP/2 환경에서는 이러한 잘못된 요청을 감지하여 400 Bad Request 응답을 반환하게 된다.
② HTTP/1.1 사용 및 ModSecurity 규칙 설정 예
[그림 30]은 HTTP/1.1 환경에서 ModSecurity를 이용하여 보안 규칙들을 설정한 후 HTTP Request Smuggling 공격을 수행한 예시이다. ModSecurity의 규칙 설정을 통해 Transfer-Encoding: chunked를 감지하고, Content-Length와 Transfer-Encoding: chunked가 동시에 사용될 때, 잘못된 줄바꿈(\r\n)이 포함된 헤더, 콜론(:)이 포함된 잘못된 헤더 이름, 요청 메서드에 공백이 포함된 경우를 감지하여 400 Bad Request로 응답한다. 이러한 설정을 통해 HTTP Request Smuggling 공격을 효과적으로 방지할 수 있다.
07. 마무리
지금까지 HTTP Request Smuggling의 기본 개념과 CL.TE, TE.CL을 이용한 공격 기법 및 대응 방안에 대해 살펴보았다. HTTP Request Smuggling은 Front-end 와 Back-end 서버 간의 요청 해석 차이를 악용하여 발생하는 취약점으로 공격자가 악의적인 요청을 통해 서버 간 통신을 조작할 수 있게 된다.
HTTP Request Smuggling을 방지하기 위해서는 서버 구성 요소 간의 일관된 요청 해석 방법을 채택하고 Content-Length와 Transfer-Encoding 헤더를 적절히 검증하는 것이 중요하다. 더불어 최신 웹 서버와 프레임워크의 보안 패치를 주기적으로 적용하고 HTTP 요청 헤더를 엄격히 검증하는 정책을 수립하는 것도 효과적인 대응 방안이 될 수 있다.
이처럼 HTTP Request Smuggling은 서버 간 통신의 복잡성 증가와 함께 그 위험성이 높아지고 있으며 잘못된 설정이나 구성으로 인해 쉽게 발생할 수 있는 취약점이다. 따라서 웹 애플리케이션의 보안을 강화하기 위해서는 HTTP Request Smuggling 취약점을 지속적으로 연구하고 보안 모니터링 및 테스트를 통해 취약점을 사전에 발견하고 수정하는 것이 필요하다.
웹 애플리케이션의 복잡성이 증가하는 한편 공격 기법 역시 고도화됨에 따라 새로운 공격이 지속적으로 나타날 수 있다. 따라서 웹 개발자와 보안 전문가는 HTTP Request Smuggling을 포함한 다양한 취약점에 대해 지속적인 관심을 가지고 보안 강화 방안을 모색하여 안전한 웹 환경을 유지해야 한다. 이러한 노력을 통해 안전한 소프트웨어 환경을 구축하고 사용자들에게 신뢰받는 웹 서비스를 제공할 수 있을 것이다.
08. 참고자료
1.https://portswigger.net/web-security/request-smuggling
2.https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
3.https://velog.io/@thelm3716/HTTP-request-smuggling#-04-http-request-smuggling-활용
4.https://www.hahwul.com/cullinan/http-request-smuggling/
5.https://guleum.com/170
6.https://book.hacktricks.xyz/v/kr/pentesting-web/http-request-smuggling
7.https://w01fgang.tistory.com/m/152
8.https://httpd.apache.org/docs/2.4/howto/http2.html
9.https://httpd.apache.org/docs/2.2/ko/mod/mod_headers.html