특수 HTTP 헤더
Reading time: 10 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
단어 목록 & 도구
- https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers
- https://github.com/rfc-st/humble
위치를 변경할 헤더
IP 출처 재작성:
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded: 127.0.0.1
Forwarded-For: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-ProxyUser-Ip: 127.0.0.1
X-Original-URL: 127.0.0.1
Client-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Host: 127.0.0.1
True-Client-IP: 127.0.0.1
Cluster-Client-IP: 127.0.0.1
Via: 1.0 fred, 1.1 127.0.0.1
Connection: close, X-Forwarded-For
(hop-by-hop 헤더 확인)
위치 재작성:
X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console
Hop-by-Hop 헤더
Hop-by-Hop 헤더는 end-to-end 헤더와는 달리 현재 요청을 처리 중인 proxy에서 처리되고 소비되도록 설계된 헤더입니다.
Connection: close, X-Forwarded-For
HTTP Request Smuggling
Content-Length: 30
Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
Expect 헤더
클라이언트가 Expect: 100-continue
헤더를 보내고 서버가 HTTP/1.1 100 Continue
로 응답하여 클라이언트가 요청 본문 전송을 계속하도록 허용할 수 있습니다. 다만 일부 프록시는 이 헤더를 제대로 좋아하지 않습니다.
Expect: 100-continue
의 흥미로운 결과:
- 본문을 가진 HEAD 요청을 보냈을 때, 서버가 HEAD 요청에는 본문이 없다는 점을 고려하지 않아 타임아웃까지 연결을 열어 둔 경우가 있음.
- 일부 서버는 응답에 소켓에서 읽은 랜덤 데이터, 비밀 키 등의 이상한 데이터를 보냈거나, 프론트엔드가 헤더 값을 제거하지 못하도록 허용함.
- 또한 백엔드가 100 응답 대신 400 응답으로 응답하여
0.CL
desync가 발생하기도 했습니다. 이 경우 프록시 프론트엔드는 초기 요청의 본문 전송을 준비하고 있었기 때문에 본문을 보내고, 백엔드는 이를 새로운 요청으로 받아들였습니다. Expect: y 100-continue
같은 변형도0.CL
desync를 유발함.- 백엔드가 404로 응답한 유사한 오류는
CL.0
desync를 생성했는데, 이는 악성 요청이Content-Length
를 표시했기 때문에 백엔드가 악성 요청 + 다음 요청(피해자)의Content-Length
바이트를 보내서 큐가 비동기화된 사례입니다. 백엔드는 악성 요청에 대해 404 응답을 보내고 피해자 요청들의 응답을 뒤이어 보냈지만, 프론트엔드는 단 하나의 요청만 보냈다고 생각하여 두 번째 응답을 다른 피해자에게 전송하고 그 응답이 다시 다음 요청으로 전달되는 등의 문제가 발생했습니다.
HTTP Request Smuggling에 대한 자세한 내용은 다음을 확인하세요:
HTTP Request Smuggling / HTTP Desync Attack
캐시 헤더
서버 캐시 헤더:
X-Cache
응답에서 값이 **miss
**이면 요청이 캐시되지 않았음을, **hit
**이면 캐시되었음을 나타낼 수 있습니다.- 유사한 동작을 하는 헤더로 **
Cf-Cache-Status
**가 있습니다. - **
Cache-Control
**은 자원이 캐시되는지 및 다음에 언제 다시 캐시될지를 나타냅니다:Cache-Control: public, max-age=1800
- **
Vary
**는 응답에서 자주 사용되며, 일반적으로 캐시 키에 포함되지 않는 추가 헤더들을 캐시 키의 일부로 취급함을 표시합니다. - **
Age
**는 객체가 프록시 캐시에 머문 시간을 초 단위로 정의합니다. Server-Timing: cdn-cache; desc=HIT
또한 자원이 캐시되었음을 나타냅니다.
Cache Poisoning and Cache Deception
로컬 캐시 헤더:
Clear-Site-Data
: 제거해야 할 캐시 유형을 지정하는 헤더:Clear-Site-Data: "cache", "cookies"
Expires
: 응답이 만료되는 날짜/시간을 포함:Expires: Wed, 21 Oct 2015 07:28:00 GMT
Pragma: no-cache
는Cache-Control: no-cache
와 동일Warning
: 일반 HTTP 헤더로 메시지 상태의 가능한 문제에 대한 정보를 포함합니다. 응답에 여러Warning
헤더가 나타날 수 있습니다. 예:Warning: 110 anderson/1.3.37 "Response is stale"
조건부 요청
If-Modified-Since
및If-Unmodified-Since
헤더를 사용하는 요청은 응답 헤더의 **Last-Modified
**가 다른 시간을 포함하는 경우에만 데이터가 반환됩니다.If-Match
및 **If-None-Match
**을 사용하는 조건부 요청은 Etag 값을 사용하여 데이터(Etag)가 변경된 경우에만 웹 서버가 응답 내용을 전송합니다.Etag
는 HTTP 응답에서 가져옵니다.- Etag 값은 보통 응답의 **내용(content)**을 기반으로 계산됩니다. 예를 들어
ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"
는Etag
가 37 바이트의 Sha1임을 나타냅니다.
Range 요청
Accept-Ranges
: 서버가 range 요청을 지원하는지, 지원한다면 어떤 단위로 범위를 표현할 수 있는지 나타냅니다.Accept-Ranges: <range-unit>
Range
: 서버가 반환해야 할 문서의 부분을 나타냅니다. 예를 들어Range:80-100
은 원본 응답의 바이트 80~100을 반환하며 상태 코드는 206 Partial Content가 됩니다. 또한 요청에서Accept-Encoding
헤더를 제거하는 것을 잊지 마세요.- 이는 통상적으로 이스케이프되는 반사된 javascript 코드를 임의로 포함한 응답을 얻는 데 유용할 수 있습니다. 다만 이를 악용하려면 요청에 해당 헤더들을 주입해야 합니다.
If-Range
: 주어진 etag나 날짜가 원격 자원과 일치하는 경우에만 충족되는 조건부 범위 요청을 만듭니다. 서로 호환되지 않는 버전의 리소스로부터 두 개의 범위를 다운로드하지 않도록 방지하기 위해 사용됩니다.Content-Range
: 부분 메시지가 전체 바디 메시지의 어디에 속하는지를 나타냅니다.
메시지 본문 정보
Content-Length
: 리소스의 크기(십진수 바이트 수).Content-Type
: 리소스의 미디어 타입을 나타냅니다.Content-Encoding
: 압축 알고리즘을 지정하는 데 사용됩니다.Content-Language
: 대상 청중을 위한 인간의 언어를 설명하여 사용자가 선호하는 언어에 따라 구분할 수 있게 합니다.Content-Location
: 반환된 데이터의 대체 위치를 나타냅니다.
pentest 관점에서는 이 정보가 보통 "쓸모없다"보여질 수 있지만, 자원이 401 또는 403으로 보호되고 있고 이 정보를 얻을 수 있는 어떤 방법을 찾을 수 있다면 이는 흥미로울 수 있습니다.
예를 들어 HEAD 요청에서 **Range
**와 **Etag
**의 조합은 HEAD 요청을 통해 페이지의 내용을 leak할 수 있습니다:
Range: bytes=20-20
헤더를 가진 요청과 응답에ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"
가 포함된 경우, 바이트 20의 SHA1이ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y
임을 leaking 하고 있는 것입니다.
서버 정보
Server: Apache/2.4.1 (Unix)
X-Powered-By: PHP/5.3.3
제어
Allow
: 이 헤더는 리소스가 처리할 수 있는 HTTP 메서드를 전달하는 데 사용됩니다. 예:Allow: GET, POST, HEAD
는 해당 리소스가 이러한 메서드를 지원함을 나타냅니다.Expect
: 클라이언트가 요청 처리를 위해 서버가 충족해야 하는 기대사항을 전달하는 데 사용됩니다. 일반적인 사용 사례는 큰 데이터 페이로드를 전송하려는 의도를 알리는Expect: 100-continue
헤더로, 클라이언트는 전송을 계속하기 전에100 (Continue)
응답을 기다립니다. 이 메커니즘은 서버 확인을 대기함으로써 네트워크 사용을 최적화하는 데 도움이 됩니다.
다운로드
응답에서 Content-Disposition
헤더는 파일을 웹페이지 내에서 표시할지(inline) 아니면 attachment로 처리할지(다운로드) 지시합니다. 예를 들어:
Content-Disposition: attachment; filename="filename.jpg"
이는 "filename.jpg"라는 파일이 다운로드되어 저장될 의도임을 의미합니다.
보안 헤더
콘텐츠 보안 정책 (CSP)
Content Security Policy (CSP) Bypass
Trusted Types
CSP를 통해 Trusted Types를 강제하면 애플리케이션을 DOM XSS 공격으로부터 보호할 수 있습니다. Trusted Types는 수립된 보안 정책을 준수하는 특정하게 생성된 객체만이 위험한 web API 호출에 사용되도록 보장하여 JavaScript 코드를 기본적으로 안전하게 합니다.
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => str.replace(/\</g, '<').replace(/>/g, '>');
});
}
// Assignment of raw strings is blocked, ensuring safety.
el.innerHTML = "some string" // Throws an exception.
const escaped = policy.createHTML("<img src=x onerror=alert(1)>")
el.innerHTML = escaped // Results in safe assignment.
X-Content-Type-Options
이 헤더는 MIME type sniffing을 방지합니다. 이는 XSS 취약점으로 이어질 수 있는 행위이며, 브라우저가 서버에서 지정한 MIME 타입을 존중하도록 보장합니다.
X-Content-Type-Options: nosniff
X-Frame-Options
clickjacking을 방지하기 위해, 이 헤더는 문서가 <frame>
, <iframe>
, <embed>
, 또는 <object>
태그에 어떻게 임베드될 수 있는지를 제한하며, 모든 문서가 임베딩 권한을 명시적으로 지정하도록 권장합니다.
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) 및 Cross-Origin Resource Sharing (CORS)
CORP는 웹사이트가 로드할 수 있는 리소스를 지정하는 데 중요하며, 교차 사이트 leaks를 완화합니다. CORS는 반면에 보다 유연한 교차 출처 리소스 공유 메커니즘을 허용하여 특정 조건에서 동일 출처 정책을 완화합니다.
Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
교차 출처 임베더 정책 (COEP) 및 교차 출처 오퍼너 정책 (COOP)
COEP와 COOP는 교차 출처 격리를 가능하게 하는 데 필수적이며 Spectre와 유사한 공격의 위험을 크게 줄입니다. 이들은 각각 교차 출처 리소스의 로딩과 교차 출처 창과의 상호작용을 제어합니다.
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups
HTTP Strict Transport Security (HSTS)
마지막으로, HSTS는 브라우저가 서버와 오직 보안된 HTTPS 연결을 통해서만 통신하도록 강제하는 보안 기능으로, 이를 통해 개인정보 보호와 보안을 향상시킵니다.
Strict-Transport-Security: max-age=3153600
헤더 이름 대소문자 우회
HTTP/1.1은 헤더 필드 이름을 대소문자를 구별하지 않음으로 정의합니다 (RFC 9110 §5.1). 그럼에도 불구하고, 커스텀 미들웨어, 보안 필터, 또는 비즈니스 로직에서 수신된 문자 그대로의 헤더 이름을 먼저 정규화하지 않고 비교하는 경우가 매우 흔합니다(예: header.equals("CamelExecCommandExecutable")
). 만약 이러한 검사들이 대소문자 구분으로 수행된다면, 공격자는 단순히 같은 헤더를 다른 대소문자 표기로 전송하는 것만으로 우회할 수 있습니다.
Typical situations where this mistake appears:
- 요청이 민감한 컴포넌트에 도달하기 전에 “위험한” 내부 헤더를 차단하려는 커스텀 허용/거부 목록.
- 리버스-프록시 의사 헤더의 사내 구현(예:
X-Forwarded-For
sanitisation). - 관리/디버그 엔드포인트를 노출하고 인증이나 명령 선택에 헤더 이름을 사용하는 프레임워크.
우회 악용
- 서버 측에서 필터링되거나 검증되는 헤더를 식별합니다(예: 소스 코드, 문서, 오류 메시지를 통해).
- 같은 헤더를 다른 대소문자 표기(혼합 대/소문자 또는 모두 대문자)로 전송합니다. HTTP 스택은 일반적으로 헤더를 사용자 코드가 실행된 후에 정규화하므로, 취약한 검사를 건너뛸 수 있습니다.
- 하위 구성요소가 헤더를 대소문자 구분 없이 처리한다면(대부분 그렇다), 공격자가 제어한 값을 수용하게 됩니다.
예시: Apache Camel exec
RCE (CVE-2025-27636)
취약한 버전의 Apache Camel에서 Command Center 라우트는 신뢰할 수 없는 요청을 차단하기 위해 CamelExecCommandExecutable
및 CamelExecCommandArgs
헤더를 제거하려고 합니다. 비교는 equals()
로 수행되어 정확히 일치하는 소문자 이름만 제거되었습니다.
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
curl "http://<IP>/command-center" \
-H "CAmelExecCommandExecutable: ls" \
-H "CAmelExecCommandArgs: /"
헤더가 exec
컴포넌트에 필터링 없이 전달되어 Camel 프로세스 권한으로 remote command execution이 발생합니다.
탐지 및 완화
- 모든 헤더 이름을 단일 케이스(보통 lowercase)로 정규화하세요 — allow/deny 비교를 수행하기 전에.
- 의심스러운 중복을 거부하세요:
Header:
와HeAdEr:
가 동시에 존재하면 이상으로 처리하세요. - 정규화(canonicalisation) 후에 적용되는 positive allow-list를 사용하세요.
- 관리 엔드포인트는 인증과 네트워크 분리로 보호하세요.
참고 자료
- CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
- https://web.dev/security-headers/
- https://web.dev/articles/security-headers
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.