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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
inference-gateway-PoC — PoC — cross-origin 요청이 inference-gateway에서 구성된 provider API 키를 재사용함 (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4). | Kitploit
도구/GitHubGitHub/squeeze440/inference-gateway-poc
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingAuthenticationAPI Security
GitHubsqueeze440/inference-gateway-poc

inference-gateway-PoC

PoC — cross-origin 요청이 inference-gateway에서 구성된 provider API 키를 재사용함 (GHSA-5293-fcm6-fh8v, CVE-2026-87009, CVSS 5.4).

저장소 보기
14시간 24분 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

inference-gateway: 보안 권고

연구자Dostxodjayev Abdullox (@squeeze440)
권고GHSA-5293-fcm6-fh8v
CVECVE-2026-87009
CVSS 3.15.4 (Medium) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L
취약점CWE-352, CWE-306, CWE-346
상태v0.46.0에서 수정됨

요약: inference-gateway는 0.0.0.0에 바인딩되며 기본적으로 인증이 비활성화된 상태(AUTH_ENABLED=false)로 제공되고, ANY /proxy/:provider/*path 패스스루 라우트는 호출자가 제공한 Authorization 헤더를 무조건 제거한 뒤 게이트웨이 운영자가 서버에 구성한 자체 프로바이더 API 키로 교체하여 업스트림으로 전달합니다. CORS 정책도, 어떤 종류의 CSRF 보호도 없어, 피해자의 브라우저가 방문하는 어떤 웹 페이지든 피해자 자신의 OpenAI/Anthropic 등 계정을 통해 과금되는 LLM 요청을 조용히 실행시킬 수 있습니다.

제품: inference-gateway/inference-gateway — 자체 호스팅, 클라우드 네이티브 LLM 게이트웨이 (Go, Gin).

테스트 버전: 커밋 6677da6afd0a606899f833c2351635edeef386f5 (main, 2026-08-04). 영향 범위: <= 0.45.0.

세부 사항

세 가지 독립적인 사실이 결합하여 이 버그를 만듭니다.

1. 인증이 꺼져 있고 바인딩이 기본적으로 공개되어 있습니다. config/config.go:77 — AuthConfig.Enabled의 기본값은 false입니다. config/config.go:94 — ServerConfig.Host의 기본값은 0.0.0.0입니다. 인증이 비활성화되면 NewOIDCAuthenticatorMiddleware (api/middlewares/auth.go:27-30)는 OIDCAuthenticatorNoop을 반환하며, 그 Middleware() (api/middlewares/auth.go:48-52)는 순수한 패스스루입니다. 이 모드에서는 어떤 라우트에도 요청별 신원 확인이 없습니다. 퀵스타트 examples/docker-compose/basic/docker-compose.yml은 AUTH_ENABLED를 설정하지 않은 채 8080:8080을 게시하므로, 문서화된 시작 경로는 정확히 이 구성을 만들어냅니다.

2. /proxy/:provider/*path는 항상 운영자 자신의 프로바이더 키를 주입합니다. api/routes.go:102-131 (ProxyHandler)는 applyProviderAuth, api/routes.go:287-312를 호출합니다:

root@kitploit:~
func applyProviderAuth(req *http.Request, provider core.IProvider) error {
	req.Header.Del("Authorization")          // caller's own Authorization header is discarded
	token := provider.GetToken()             // the operator's configured key (env var, e.g. OPENAI_API_KEY)
	switch provider.GetAuthType() {
	case constants.AuthTypeBearer:
		req.Header.Set("Authorization", "Bearer "+token)
	...

호출자 자신의 자격 증명이 사용되는 코드 경로는 존재하지 않습니다. 설계상 항상 게이트웨이에 구성된 키로 대체합니다. 사실 1과 결합하면, 인증되지 않은 호출자가 운영자의 실제 키를 공짜로 부여받게 됩니다.

3. 미들웨어 체인 어디에도 CORS 정책과 CSRF 보호가 존재하지 않습니다. cmd/gateway/main.go:271은 gin.New()로 라우터를 구성합니다(기본 미들웨어 없음). 체인(:273-290)은 otel → logger → telemetry → OIDC auth → guardrails → MCP입니다. go.mod/go.sum에는 CORS 패키지가 없습니다. Access-Control-Allow-Origin 헤더는 전혀 전송되지 않습니다. 프록시 핸들러는 동작하는 데 사용자 정의 헤더나 CORS-안전하지 않은 Content-Type이 필요하지 않습니다(원시 본문을 전달한 뒤 api/routes.go:254에서 아웃바운드 Content-Type을 application/json으로 덮어씁니다). 따라서 "단순" 교차 출처 fetch()(Content-Type: text/plain, 사용자 정의 헤더 없음)는 브라우저에 의해 프리플라이트 없이 전송됩니다. 서버 측 과금 요청은 브라우저의 읽기 측 CORS 시행과 무관하게 완료됩니다.

순 효과: 게이트웨이가 해당 브라우저에서 도달 가능한 동안(루프백, LAN, 또는 운영자가 문서화된 8080:8080 게시 패턴을 따른 경우 공용), 피해자의 브라우저가 방문하는 어떤 출처든 운영자의 실제 프로바이더 계정을 통해 공격자가 선택한 임의의 채팅 완성을 실행시킬 수 있으며, 인증이 전혀 없고 사용자에게 보이는 표시도 없습니다.

개념 증명

두 개의 서로 다른 루프백 출처(게이트웨이는 127.0.0.1, 공격자 페이지는 127.0.0.2) 사이에서 실제 Chrome 브라우저가 진정한 교차 출처 요청을 수행하는 것을 동적으로 종단 간 확인했습니다. poc/를 참조하세요:

  • poc/attacker_site/attack.html — 공격자 출처에서 제공되는 정확한 페이지로, 로드 시 유일한 동작은 /proxy/openai/chat/completions에 대한 fetch() 하나입니다.
  • poc/mock_upstream.py — api.openai.com을 대신하며, 수신한 Authorization 헤더, Origin, 본문을 기록합니다.
  • poc/README.md — 전체 실행 단계.

관찰된 결과: 교차 출처 브라우저 요청(Origin: http://127.0.0.2:8000)이 Authorization: Bearer sk-proj-VICTIM-REAL-BILLED-KEY-...와 공격자가 선택한 본문 {"messages":[{"role":"user","content":"CSRF-DRIVEBY-MARKER-8271"}]}을 담은 채 모의 업스트림에 도달했습니다. 공격자 페이지는 어떤 자격 증명도 보유하지 않았고, 보지도 못했으며, 요구받지도 않았습니다. 브라우저 네트워크 검사로 127.0.0.2:8000 페이지에서 POST http://127.0.0.1:8081/proxy/openai/chat/completions [200]이 발생했음이 확인되었습니다. 전체 브라우저 기반 증거(네트워크 로그, 스크린샷)는 GHSA-5293-fcm6-fh8v에 첨부되어 있습니다.

영향

문서화된 기본 구성으로 inference-gateway를 실행하는 모든 운영자는, 게이트웨이의 포트에 도달할 수 있는 브라우저에서 접근 가능한 어떤 웹 페이지든 자신이 구성한 프로바이더 API 키를 사용할 수 있게 됩니다. 이때 "게이트웨이 주소로 HTTP 요청을 보낼 수 있다"는 것 외에 자격 증명, 쿠키, 특별한 네트워크 위치가 필요하지 않습니다. 구체적으로: 운영자 자신의 프로바이더 계정에서의 무단 과금/할당량 소비가, 게이트웨이가 실행 중인 동안 운영자(또는 같은 LAN의 누구든)가 열어둔 제3자 웹사이트, 광고, 또는 손상된 페이지에 의해 맹목적으로 유발됩니다. 브라우저가 공격자의 모델 출력 읽기를 차단하므로(CORS 헤더 없음), 이는 읽기 프리미티브가 아닌 맹목적 강제 트랜잭션입니다.

취약점

  • CWE-352 교차 사이트 요청 위조(Cross-Site Request Forgery) — 안티 CSRF 토큰도, Origin/Sec-Fetch-Site 검사도, CORS 제한도 없이 브라우저가 발행한 교차 출처 요청을 통해 수행되는 비용이 큰 상태 변경 작업입니다.
  • CWE-306 중요 기능에 대한 인증 누락 — AUTH_ENABLED=false(문서화된 기본값)일 때 /health를 제외한 모든 라우트에 요청별 신원 확인이 전혀 없습니다.
  • CWE-346 출처 검증 오류 — 미들웨어 체인 어디에도 CORS 정책이나 출처 허용 목록이 없습니다.

해결 방안

v0.46.0에서 수정되었습니다(유지관리자가 기본값을 강화함). 권장 조치:

  1. /proxy/:provider/*path(및 기타 상태 변경 라우트)에 사용자 정의된, 안전 목록에 없는 헤더를 요구하여, 교차 출처 호출자에게 CORS 프리플라이트를 강제하고 게이트웨이가 출처 허용 목록을 시행할 지점을 마련합니다. 이는 인증을 활성화하지 않고도 "단순 요청" 우회를 차단합니다.
  2. SERVER_HOST의 기본값을 0.0.0.0에서 127.0.0.1로 변경하여, 더 넓은 인터페이스에 대한 명시적 옵트인을 요구합니다(동일한 부류의 버그에 대해 Ollama가 그랬던 것처럼).
  3. AUTH_ENABLED=false이고 SERVER_HOST가 루프백이 아닐 때 시작 경고를 출력하거나 시작을 거부합니다.
  4. README.md / Configurations.md에 위험을 문서화합니다.

크레딧

Dostxodjayev Abdullox (@squeeze440)

도구 다운로드