🇰🇷 한글 설명
Headroom의 LLM 프록시가 x-headroom-user-id 헤더를 통해 메모리 소유자를 결정할 때 호출자의 신원을 검증하지 않는 취약점입니다. 공격자는 다른 사용자의 ID를 헤더에 삽입하여 해당 사용자의 LLM 메모리를 읽거나 쓸 수 있습니다. 특히 기본 제공되는 docker-compose 설정이 인증 없이 네트워크에 노출될 수 있어 위험합니다.
💡 쉬운 설명
사용자 ID를 가짜로 적어서 보내면 시스템이 이를 그대로 믿어버리는 문제입니다. 이로 인해 다른 사람의 대화 기록이나 개인적인 AI 메모리를 몰래 훔쳐보거나 조작할 수 있습니다.
🇺🇸 원문 (English)
Headroom's LLM proxy derives the memory owner from the x-headroom-user-id request header. The header is read directly at several points in headroom/proxy/handlers/openai.py, including the chat completion and websocket paths, and nothing binds the value to the caller. A client can therefore name another user's identifier and read or write that user's stored LLM memory. The fix introduces a single resolve_memory_identity seam in headroom/proxy/identity.py that honors the header only for loopback or allowlisted callers and otherwise binds the identity to the proxy-token fingerprint or the operating system user. The pip console script binds 127.0.0.1 by default, but the reference docker-compose.yml ships --host 0.0.0.0 with published ports and no required HEADROOM_PROXY_TOKEN, which the server itself warns about at startup, so a deployment following the shipped compose exposes the affected data-plane routes to the network without authentication.
📍 영향받는 시스템
Headroom LLM proxy (docker-compose를 사용하여 0.0.0.0으로 배포된 환경)
⚔️ 공격 벡터
HTTP 요청 헤더의 x-headroom-user-id 값을 타인의 ID로 조작하여 전송
🛡️ 대응 방법
headroom/proxy/identity.py에 resolve_memory_identity 로직을 적용하고, HEADROOM_PROXY_TOKEN을 설정하여 인증을 강제해야 합니다.
🔧 검증 코드
명령어 실행 시 인증 없이 타인의 ID로 요청이 성공(200 OK)하면 취약한 상태입니다.
curl -I -H 'x-headroom-user-id: target-user-id' http://localhost:port/v1/chat/completions