← 기술 지식

기술 지식 / 보안 / 입력·웹 보안

프록시와 앱이 공유해야 할 HTTP 해석 경계

Host·전달 헤더의 신뢰 출처와 요청 길이 해석을 구분하고 외부 링크·다중 프록시·직접 접근·연결 폐기의 검증을 설명합니다.

보안 · 원리·구현·운영
기술 지식 트리

HTTP 경계 검증의 기본 모델은 외부 바이트를 여러 계층이 같은 요청으로 해석하도록 만드는 것입니다. origin을 만드는 입력과 라우팅에 쓰는 Host를 구분하고, 프록시와 backend가 본문 길이·헤더 문법·연결 재사용 경계를 같은 규칙으로 처리해야 합니다. 어느 한 계층의 필터가 통과했다는 사실만으로 전체 체인의 안전한 해석을 증명할 수는 없습니다.

사용자 제공 Host와 공식 origin의 신뢰 경계

비밀번호 재설정 메일의 링크를 request.host + path로 만든다고 합시다. Host가 공격자가 선택할 수 있는 요청 입력인데도 그대로 쓰면 공식 메일 안에 다른 사이트 주소가 들어갈 수 있습니다. TLS 인증서가 우리 서버의 것이라는 사실은 요청 헤더가 서비스의 신뢰된 설정이라는 뜻이 아닙니다.

공식 외부 링크는 등록된 origin에서 만듭니다. 여러 고객 도메인을 지원하면 검증된 테넌트·등록 도메인 매핑에서 선택하며, 현재 Host가 그 테넌트의 허용 도메인인지 확인합니다. 캐시 키·절대 redirect·OAuth callback에도 같은 신뢰 구분이 필요합니다.

전달 헤더의 프록시 검증과 신뢰 조건

요청을 진단할 때는 직접 접근/프록시 경로 → 각 hop의 헤더 제거·재작성 → 앱이 채택한 canonical host → 생성된 링크·redirect·cache key를 순서대로 기록합니다. 여러 헤더가 서로 다른 Host를 주장하면 어떤 값이 먼저 선택되는지 추측하지 말고 요청을 거절하거나 하나의 정규화 규칙으로 모든 계층이 같은 값을 사용하게 합니다.

값 신뢰할 조건 잘못된 가정
Host·:authority 허용 가상 호스트와 프로토콜 일관성 검사 서버 공식 origin과 항상 같음
X-Forwarded-Host 신뢰 프록시가 외부값 제거 후 재작성 이름에 Forwarded가 있으니 안전함
Forwarded의 client 주소 실제 hop·프록시 주소 정책에 맞게 해석 맨 앞 주소가 무조건 실제 사용자
등록 origin 관리 경로에서 검증한 설정 임의 요청값으로 즉시 갱신 가능

프록시가 한 대라는 전제에서 고정 hop 수만 세면, 앞단에 프록시가 더 붙거나 앱에 직접 접근할 수 있게 된 순간 전달 헤더의 위치를 잘못 믿게 됩니다. 실제 요청 경로에서 각 프록시가 어떤 헤더를 지우고 다시 쓰는지 확인한 뒤, 그 경로의 신뢰할 프록시만 전달값의 근거로 인정해야 합니다. backend 직접 경로는 차단하거나 프록시를 거칠 때와 같은 검증을 적용하고, 여러 헤더에 상충하는 Host 값이 오면 캐시 키와 라우팅이 서로 다른 값을 사용하지 않도록 한 해석 규칙으로 거절합니다.

프런트·백엔드 요청 경계 해석 일치

구체적인 검증은 공격 문자열을 재현하는 대신 합성 요청의 파서 결과를 비교하는 방식으로도 시작할 수 있습니다. 프런트가 요청 하나로 분류한 바이트 수·backend가 처리한 바이트 수·다음 요청의 시작 offset·연결 재사용 여부를 기록하고, 모호한 입력은 양쪽 모두 같은 거절과 연결 폐기를 보여야 합니다. 한 파서만 관대하면 정상 응답 여부와 무관하게 경계 불일치가 남습니다.

HTTP 연결 재사용에서는 한 요청이 끝난 바이트 뒤에 다음 요청이 이어집니다. 프런트 프록시가 길이를 L1로 읽고 백엔드가 L2로 읽으면, 한쪽이 본문으로 본 바이트를 다른 쪽은 다음 요청으로 해석할 수 있습니다. request smuggling의 핵심은 이 메시지 경계 불일치입니다. 요청 본문 내용의 문자열 필터만으로 고칠 수 없습니다.

같은 바이트열을 두 파서가 다르게 나누면 안 됩니다외부 요청 바이트. 프런트 HTTP 파서: 경계·헤더 검증. 백엔드 HTTP 파서: 동일한 요청 의미. 다음 요청 시작 위치 일치비신뢰 입력정규화된 전달경계 보존외부 요청 바이트프런트 HTTP 파서경계·헤더 검증백엔드 HTTP 파서동일한 요청 의미다음 요청 시작 위치 일치
같은 바이트열을 두 파서가 다르게 나누면 안 됩니다 화살표는 요청 전달 경로입니다. 각 계층의 길이·헤더·프로토콜 변환 해석이 일치해야 하며 모호한 입력은 연결을 재사용하지 않고 거절합니다. 공격용 바이트 payload는 포함하지 않습니다.
그림을 글로 읽기
  • 외부 요청 바이트
  • 프런트 HTTP 파서: 경계·헤더 검증
  • 백엔드 HTTP 파서: 동일한 요청 의미
  • 다음 요청 시작 위치 일치
  1. 외부 요청 바이트 → 프런트 HTTP 파서: 비신뢰 입력
  2. 프런트 HTTP 파서 → 백엔드 HTTP 파서: 정규화된 전달
  3. 백엔드 HTTP 파서 → 다음 요청 시작 위치 일치: 경계 보존

프런트와 backend가 같은 요청으로 처리하려면 Content-Length와 Transfer-Encoding이 충돌하는 경우, 길이값이 중복되는 경우, 헤더 문법·줄바꿈이 잘못된 경우를 각 파서가 어떻게 읽는지 맞춰야 합니다. HTTP/2에서 HTTP/1.1로 변환되는 지점도 별도의 경계로 보고, 한 계층만 모호한 입력을 관대하게 수락하지 않도록 안전하게 거절하거나 정규화하는 정책과 결과를 일치시킵니다. HTTP/2를 켰다는 사실만으로 뒤쪽 변환 경계의 해석이 안전해지는 것은 아닙니다.

요청 거절 뒤 연결 폐기와 재사용 방지

파서가 오류를 발견했어도 남은 바이트 위치를 확정할 수 없는 연결을 풀에 돌려주면 다음 사용자의 요청에 영향을 줄 수 있습니다. 모호한 경계의 오류는 안전하게 연결을 폐기하고, 프런트·백엔드 모두 같은 정책을 적용합니다. timeout·본문 제한을 둬도 파서 의미의 불일치를 없애지는 못합니다.

라이브러리·프록시의 보안 업데이트와 권장 설정을 적용하고, 한 제품의 단독 파서 시험만으로 실제 전체 체인을 검증했다고 보지 않습니다. WAF가 보는 문법과 실제 앱이 보는 문법이 다르면 탐지 설정에도 사각지대가 생깁니다.

허가된 격리 경로의 양측 관찰 대조

테스트용 프록시·backend 체인에서 등록되지 않은 Host, 상충하는 전달 헤더, 직접 접근을 검사합니다. 재설정 링크·redirect·캐시 항목이 신뢰된 origin만 사용하는지 확인합니다. 실사용자 메일 대신 로컬 수신함을 사용합니다.

경계 검증은 제품의 공식 회귀 테스트·안전한 합성 입력을 사용해 프런트와 백엔드가 같은 요청 수·대상·본문 길이를 관찰하는지 대조합니다. 오류 후 연결 재사용이 없는지도 확인합니다. 운영 공유 연결에 임의 공격 트래픽을 보내지 않습니다. 이 노트는 방어 설계이며 실제 프록시 체인에 대한 침투시험 결과가 아닙니다.

후속·관련 개념

함께 읽을 문서

전체 기술 지식
선택 연습 · 관련 질문 2개

질문은 이해를 확인하는 보조 자료입니다. 학습 경로와 문서의 범위는 질문 수와 독립적입니다.