예전에 재미난 글을 읽었다. 바로 이 글인데, 내용을 짧게 요약해 보자면, HTTP/2의 핵심 기능인 Stream muliplexing을 이용한 DDoS 공격을 시도해 적은 규모의 클라이언트로 초당 수억 이상의 요청을 보냈다는 내용이다.
HTTP/2
HTTP/2(Hypertext Transfer Protocol Version 2)는 SPDY를 기반으로 하고 있다. 1997년 표준화된 HTTP/1.1의 대부분을 개선한 표준으로 2015년 2월 17일 IESG에서 승인되었다.
Stream multiplexing
이 글의 주제인 CVE-2023-44487을 이해하기 위해선 HTTP/2의 핵심 기능인, Stream multiplexing에 대해서 알아볼 필요가 있다.
오늘날의 대부분의 웹페이지는 이미지, css, javascript, html등 많은 리소스를 포함한다. 사용자가 웹 페이지에 접근 시 리소스를 다운로드하기 위해 많은 TCP 통신을 하는데, 리소스 당 하나의 요청을 하게 되면서 많은 TCP 연결 비용을 지불하게 된다. 이때 HTTP/2는 단일 연결에서 Stream multiexpling 통해 서로 다른 여러 요청을 보낼 수 있게 한다.
단일 연결에서 여러 요청을 Multiplexing을 했다면, 응답받은 데이터를 처리하기 위한 Demultiplexing 과정이 필요하다. 이 과정에서 각 요청과 응답을 연결하기 위해서 Stream ID가 사용된다.
RST_STREAM
RST_STREAM은 TCP 연결을 유지하며, 일부 Stream에 대해서만 취소할 때 보내는 프레임이다. 이러한 방식은 클라이언트와 서버에서 불필요한 요청/응답을 부분적으로 취소함으로써 자원을 효율적으로 사용할 수 있도록 만들어준다.
HTTP/2 Rapid Reset
앞서 짧게 HTTP/2의 Stream multiplexing과 RST_STREAM을 살펴봤다. 그렇다면 이렇게 효율적인 기능들이 어떻게 어마어마한 DDoS 공격으로 이용됐을까? HTTP/2는 앞서 알아본 Stream multiplexing, RST_STREAM 등으로 브라우저의 연결 제한 속에서도 클라이언트는 높은 병렬처리를 가능하게 하지만, 그만큼 서버에 더 많은 요청을 보낼 수 있게된다는 점도 존재한다. 이를 위해서 HTTP/2 스펙을 살펴보면 SETTINGS_MAX_CONCURRENT_STREAMS로 최대 스트림 생성을 제한할 수 있지만, 이는 스트림 라이프 사이클 내 open 된 스트림의 제한을 두기 때문에 half-closed 상태는 포함되지 않는다. 따라서 악의적인 클라이언트가 연속적으로 요청/취소를 반복하면 설정된 스트림 개수보다 많은 스트림을 생성할 수 있다.
참고
- https://cloud.google.com/blog/ko/products/identity-security/how-it-works-http2-rapid-reset-ddos
- https://www.rfc-editor.org/rfc/rfc9113
- https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack
'독서 > 네트워크' 카테고리의 다른 글
HTTP 응답 상태 코드 (0) | 2022.01.02 |
---|---|
전송 계층 (0) | 2021.12.30 |
응용 계층 (0) | 2021.12.24 |