🇰🇷 한글 설명
mtrudel의 bandit에서 보안 결정 시 신뢰할 수 없는 입력에 의존하는 취약점으로, 인증되지 않은 공격자가 평문 HTTP 연결에서 전송 상태를 위조할 수 있습니다. Bandit.Pipeline의 determine_scheme/2 함수가 전송 계층의 secure? 플래그를 무시하고 클라이언트가 보낸 URI 스킴을 그대로 반환합니다. 1.0.0 이상 1.11.0 미만 버전이 영향을 받습니다.
💡 쉬운 설명
공격자가 일반 HTTP 연결에서 요청에 https라고 적어 보내면, 서버는 실제로는 암호화되지 않았는데도 보안 연결로 인식합니다. 이로 인해 HTTPS 리다이렉트가 건너뛰어지거나 보안 쿠키가 평문으로 전송될 수 있습니다.
🇺🇸 원문 (English)
Reliance on Untrusted Inputs in a Security Decision vulnerability in mtrudel bandit allows unauthenticated transport-state spoofing on plaintext HTTP connections.
'Elixir.Bandit.Pipeline':determine_scheme/2 in lib/bandit/pipeline.ex returns the client-supplied URI scheme verbatim, ignoring the transport's secure? flag. HTTP/1.1 absolute-form request targets (e.g. GET https://victim/path HTTP/1.1) and the HTTP/2 :scheme pseudo-header are both attacker-controlled strings that flow through this function. Over a plaintext TCP connection, a client can declare https and Bandit will set conn.scheme = :https even though no TLS was negotiated.
Downstream Plug consumers that branch on conn.scheme are silently misled: Plug.SSL's already-secure branch skips its HTTP→HTTPS redirect, cookies emitted with secure: true are sent over plaintext, audit logs record requests as having arrived over HTTPS, and CSRF/SameSite gating may make incorrect decisions.
This issue affects bandit: from 1.0.0 before 1.11.0.
📍 영향받는 시스템
Elixir bandit 1.0.0 이상 1.11.0 미만 버전을 사용하는 웹 애플리케이션
⚔️ 공격 벡터
평문 HTTP 연결에서 절대형 요청 대상(GET https://victim/path HTTP/1.1)이나 HTTP/2 :scheme 의사 헤더에 https를 넣어 conn.scheme을 조작
🛡️ 대응 방법
bandit을 1.11.0 이상으로 업그레이드 (mix.exs에서 {:bandit, "~> 1.11"} 지정 후 mix deps.update bandit)
🔧 검증 코드
출력된 버전이 1.11.0 미만이면 취약하며, 1.11.0 이상이면 패치가 적용된 것입니다. 출력이 없으면 mix.lock에 bandit이 없는 것입니다.
grep -A1 '{:bandit' mix.lock 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'