يېڭىلاندى 1 month ago
GET, POST, PUT, DELETE가 대부분의 웹 트래픽을 처리하는 동안, HTTP에는 특수한 상황을 위한 두 가지 전문적인 메서드가 있습니다: 프록시를 통한 터널링을 위한 CONNECT와 진단 에코를 위한 TRACE입니다. 하나는 필수적인 인프라입니다. 다른 하나는 우리가 대부분 비활성화해 버린 보안 취약점입니다.
CONNECT: 프록시를 투명하게 만들기
CONNECT는 HTTP가 중개자를 통한 암호화 연결을 위해 설계되지 않았기 때문에 존재합니다.
문제를 살펴봅시다: 여러분은 회사 프록시 뒤에 있고, https://bank.com을 방문하려 합니다. 프록시가 이것을 일반적인 HTTP 요청처럼 처리한다면, 트래픽을 복호화하고 내용을 읽은 다음 은행을 위해 다시 암호화해야 합니다. 이렇게 되면 종단 간 암호화가 완전히 깨집니다—프록시가 여러분의 비밀번호, 계좌 번호, 모든 것을 들여다볼 수 있게 되죠.
CONNECT는 프록시를 단순 통로로 전환하여 이 문제를 해결합니다:
이것은 프록시에게 이렇게 말하는 것입니다: "bank.com의 443 포트로 TCP 연결을 열어. 그다음 HTTP 프록시 역할은 그만둬. 내용은 보지 말고 양방향으로 바이트만 전달해."
프록시는 다음과 같이 응답합니다:
이제 프록시는 투명해집니다. 브라우저와 은행 서버는 터널을 통해 직접 TLS를 협상합니다. 프록시에는 그저 의미 없는 암호문이 흘러갈 뿐입니다—바로 의도한 대로입니다.
CONNECT가 특이한 이유
CONNECT 요청은 일반적인 HTTP와 다르게 생겼습니다:
URI가 경로가 아닙니다—목적지 호스트:포트입니다. 그리고 Proxy-Authorization은 목적지 서버가 아닌 프록시에 인증합니다.
프록시가 CONNECT를 제한하는 이유
제한 없는 CONNECT는 위험합니다. 프록시가 모든 호스트와 포트로의 CONNECT를 허용한다면, 공격, 스팸, 혹은 네트워크 통제 우회를 위한 개방형 중계기가 됩니다.
대부분의 프록시는 스스로를 이렇게 보호합니다:
포트 제한: 443 포트(HTTPS)로의 CONNECT만 허용합니다. 22 포트(SSH)로의 요청은 거부됩니다:
인증 필수: 익명 터널링은 허용하지 않습니다.
도메인 화이트리스트: 일부 회사 프록시는 승인된 목적지로만 터널링합니다.
로깅: 프록시는 터널 내용을 볼 수 없지만, 누가 어디로 터널링하는지는 기록합니다.
CONNECT는 자동으로 이루어집니다
CONNECT를 직접 볼 일은 거의 없습니다. 브라우저가 HTTP 프록시로 설정되어 있을 때, HTTPS 사이트에 대해 자동으로 CONNECT를 보냅니다:
프록시를 통한 WebSocket 연결도 같은 방식으로 작동합니다—CONNECT가 터널을 만들고, 그 안에서 WebSocket 업그레이드가 이루어집니다.
CONNECT 지원 구현하기
프록시를 직접 구현한다면:
TRACE: 독이 된 투명성
TRACE는 디버깅을 위해 설계되었습니다. 요청을 보내면 서버가 받은 것을 그대로 돌려줍니다:
서버 응답:
이렇게 하면 중간 프록시들이 추가한 헤더를 확인할 수 있습니다. 중개자가 요청을 어떻게 수정하는지 진단하는 데 유용합니다.
보안 문제
TRACE의 투명성은 크로스 사이트 트레이싱(XST, Cross-Site Tracing)이라는 취약점이 되었습니다.
브라우저는 HttpOnly 플래그로 쿠키를 보호합니다—자바스크립트가 쿠키를 읽을 수 없습니다. 하지만 TRACE는 쿠키와 인증 헤더를 포함한 모든 것을 응답 본문에 그대로 돌려줍니다:
쿠키에 HttpOnly가 설정되어 있으니 스크립트로 document.cookie를 읽을 수는 없습니다. 하지만 TRACE가 그 보호를 완전히 우회해 평문으로 돌려주는 겁니다.
TRACE는 거의 사라졌습니다
XST 때문에 TRACE는 거의 모든 현대 서버에서 기본적으로 비활성화되어 있습니다:
- Apache:
TraceEnable Off - Nginx: TRACE를 아예 지원하지 않음
- IIS: 기본적으로 필터링됨
대부분의 서버는 405 Method Not Allowed를 반환합니다. 보안 스캐너는 TRACE가 활성화되어 있으면 취약점으로 표시합니다.
Max-Forwards 헤더
TRACE는 프록시 체인을 추적하기 위해 Max-Forwards를 지원합니다:
각 프록시는 이 값을 하나씩 줄입니다. 0이 되면 그 프록시가 전달 대신 직접 응답합니다. 체인에서 어느 프록시가 문제를 일으키는지 찾을 때 유용합니다.
실제로는 TRACE 자체가 어디서나 비활성화되어 있기 때문에 아무도 이 기능을 쓰지 않습니다.
서로 다른 운명
CONNECT는 여전히 필수적입니다. 프록시를 통한 모든 HTTPS 연결이 이것을 사용합니다. 직접 볼 수는 없지만 분명히 존재합니다—회사 네트워크를 통해 암호화된 웹 브라우징을 가능하게 하는, 눈에 보이지 않는 인프라입니다.
TRACE는 반면교사입니다. 투명성을 위해 설계된 메서드가 무기가 되었습니다. 그것이 하던 역할은 이미 더 나은 도구들이 대신합니다: 브라우저 DevTools, Charles나 Fiddler 같은 프록시 인터셉터, 서버 측 로깅, 혹은 커스텀 디버그 엔드포인트:
디버깅 기능은 그대로, 보안 구멍은 없습니다.
HTTP CONNECT와 TRACE에 관한 자주 묻는 질문
프록시가 HTTPS 요청을 일반적으로 전달할 수 없는 이유는 무엇인가요?
HTTPS는 암호화되어 있습니다. 프록시가 이것을 "일반적으로" 전달하려면 트래픽을 복호화해야 합니다. 그러려면 암호화를 깨거나 가짜 인증서로 중간자 공격을 수행해야 합니다. CONNECT는 프록시가 내용을 이해하지 못한 채 암호화된 바이트를 그대로 전달하는 터널을 만들어 이 문제를 피합니다.
웹 애플리케이션에서 CONNECT를 직접 구현해야 하나요?
아니요. CONNECT는 웹 애플리케이션이 아니라 프록시 서버에서 처리합니다. 애플리케이션은 CONNECT 요청을 받지 않습니다—인프라 단에서 가로챕니다. 브라우저와 HTTP 클라이언트는 프록시를 사용하도록 설정되면 CONNECT를 자동으로 처리합니다.
TRACE는 완전히 쓸모없나요?
프로덕션 환경에서는 그렇습니다. 보안 위협만 있고 얻는 것은 없습니다. HTTP를 배우거나 격리된 환경에서 테스트할 때는 HTTP 에코가 어떻게 작동하는지 보여주는 예시가 되기도 합니다. 하지만 실제 운영 환경에서 TRACE가 활성화된 것을 마주칠 일은 거의 없을 겁니다.
서버에서 TRACE가 비활성화되었는지 어떻게 확인하나요?
405 Method Not Allowed가 돌아와야 합니다. 요청 내용이 에코된 200 응답이 돌아온다면 즉시 TRACE를 비활성화하세요.
بۇ بەت پايدىلىق بولدىمۇ؟