HTTP Request Smuggling (요청 스머글링)이란?
**HTTP 요청 스머글링(HTTP Request Smuggling, HRS)**이란,
**프론트엔드 서버(리버스 프록시, 로드 밸런서 등)**와 백엔드 서버(애플리케이션 서버) 간
HTTP 요청 해석 차이점을 악용하여 요청을 변조하거나 몰래 끼워 넣는 공격 기법을 의미합니다.
간단히 말하면,
"앞단 서버는 하나의 요청이라 생각했지만, 뒷단 서버는 두 개 이상의 요청으로 인식하여
공격자가 숨겨둔 악의적 요청이 몰래 처리되는 것"
이라고 할 수 있습니다.
어떻게 발생하는가?
HTTP 요청 본문의 길이를 명시하는 Content-Length 헤더와
요청을 여러 개로 구분하는 Transfer-Encoding: chunked 헤더의 해석 차이를 이용합니다.
- 프론트 서버와 백엔드 서버가 서로 다르게 이 두 헤더를 해석하면,
- 공격자가 숨긴 두 번째 요청이 정상 요청에 끼워 넣어져 처리될 수 있습니다.
예시 흐름
POST / HTTP/1.1
Host: example.com
Content-Length: 50
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: example.com
- 프론트 서버는 Content-Length를 기준으로 해석하여 요청 완료라 판단하지만,
- 백엔드 서버는 Transfer-Encoding을 기준으로 해석하여 뒤의 숨은 GET 요청을 별개로 처리할 수 있습니다.
주요 공격 결과
| 요청 가로채기 | 다른 사용자의 요청을 탈취할 수 있습니다. |
| 세션 하이재킹 | 세션 토큰 탈취 가능. |
| 캐시 포이즈닝 | 잘못된 응답을 캐시하여 불특정 다수에게 악성 응답을 제공할 수 있습니다. |
| 비인가 요청 전송 | 관리자 페이지 접근, CSRF 보조 공격 등. |
방어 및 대응 방법
| 단일 길이 기준 강제화 | Content-Length 또는 Transfer-Encoding 중 하나만 허용. |
| HTTP 요청 일관성 검사 | 서버 간 동일한 해석 기준 유지 (엄격한 RFC 준수). |
| 최신 웹서버/프록시 업데이트 | nginx, Apache, HAProxy 등의 보안 패치 적용. |
| WAF 규칙 강화 | WAF(Web Application Firewall)에서 의심 요청 차단. |
| input validation 강화 | HTTP 요청 헤더와 바디를 철저히 검증. |
덧붙여
HTTP Request Smuggling은 2005년에 처음 발견되었으나,
2020년대 이후 클라우드 환경, API Gateway, Reverse Proxy 사용 증가로 인해 다시 부각되었습니다.
특히 Android 앱에서도 백엔드와 통신할 때 리버스 프록시를 거치는 경우, 서버 측 대응이 매우 중요합니다.
추가로
Android App 관점에서 HTTP Request Smuggling 대응 가이드
1. 앱 내부 네트워크 통신 라이브러리 설정 강화
Android 앱은 보통 OkHttp, Retrofit, HttpURLConnection 등을 통하여 서버와 통신합니다.
이를 사용하는 경우, 기본 설정만으로는 일부 우회 시도가 가능할 수도 있으므로, 아래를 꼭 지켜야 합니다.
OkHttp / Retrofit 대응
- HTTP/1.1 또는 HTTP/2 명시적 사용 (HTTP/0.9, HTTP/1.0은 지원 차단)
- Transfer-Encoding: chunked 사용 최소화
- Content-Length 헤더의 일관성 확보 (명시적 지정 권장)
val client = OkHttpClient.Builder()
.protocols(listOf(Protocol.HTTP_1_1, Protocol.HTTP_2))
.build()
- Interceptor 추가로 비정상 요청 방어
class HeaderValidationInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val headers = request.headers
// 의심스러운 헤더 검증
if (headers.names().any { it.equals("Transfer-Encoding", ignoreCase = true) }
&& headers.names().any { it.equals("Content-Length", ignoreCase = true) }) {
throw IOException("Invalid HTTP headers detected: Smuggling risk.")
}
return chain.proceed(request)
}
}
// 적용 예시
val safeClient = OkHttpClient.Builder()
.addInterceptor(HeaderValidationInterceptor())
.build()
2. 서버와 통신 시 HTTPS 강제 사용
- 반드시 HTTPS 통신만 허용할 것.
- 앱의 network_security_config.xml을 설정하여 **Cleartext Traffic(HTTP)**을 차단할 것.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
- AndroidManifest.xml에도 반영
<application
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="false">
3. 서버 측 검증 동시 강화
비록 앱에서 요청을 조심하더라도,
**서버(백엔드)**가 최종적으로 요청을 검증하고 해석하므로 서버단에서도 반드시 다음을 해야 합니다 :
| Proxy, LB 업데이트 | nginx, HAProxy 등을 최신 버전으로 유지. |
| Content-Length/Transfer-Encoding 혼용 차단 | 둘 중 하나만 허용하거나, 둘 모두 존재할 경우 요청 거부. |
| Request size 제한 | 요청 본문 크기에 상한 설정 (예: 8KB 제한). |
| 경계 테스트 수행 | BurpSuite, OWASP ZAP 등으로 Smuggling 테스트. |
4. 취약점 대응 주기적 점검
- 앱과 서버 모두 대상으로 OWASP ASVS 4.0 기준을 활용하여 정기 점검을 수행할 것.
- OWASP HTTP Request Smuggling Cheat Sheet를 참조하여 공격 패턴 업데이트 및 방어할 것.
HTTP Request Smuggling Cheat Sheet (OWASP)
맺음말
"애초에 요청이 올바르게 구성되도록 하고, 서버가 의심스러운 요청을 철벽같이 막아내는 것이
HTTP Request Smuggling을 완전히 차단하는 길"입니다.
Android 앱에서도 '안전한 요청 생성'은 매우 중요하니,
앱 단에서부터 안전한 통신을 기본으로 삼고, 서버와의 협력 체계를 단단히 다지는 것이 필수라 할수 있습니다.
'python > tips' 카테고리의 다른 글
| Linux Java TrustStore에서 오래된 인증서 예전 인증서 제거하는 방법 (1) | 2025.05.14 |
|---|---|
| Excel에서 두 시분초(예, 010203)값의 차이를 초로 계산하기 (0) | 2025.04.28 |
| jQuery 1.4에서 jQuery 3.5 이상으로 업그레이드 Plan (0) | 2025.04.22 |
| linux 지정한 날짜 이전 변경된 파일 찾기 (0) | 2025.04.22 |
| Macbook에서 brew install & uninstall (0) | 2025.04.09 |