DeepSeek Harness는 HTTP Host 헤더를 127.0.0.1로 변경하는 것만으로 샌드박스 내 공격자가 임의의 명령을 실행할 수 있게 방치했으며, 이는 CVSS 기준으로 9.4점을 기록했습니다. 이 결함은 단 한 번의 잘못된 신뢰 결정이 어떻게 보호 경계를 개방된 백도어로 바꿀 수 있는지를 보여줍니다.
버그가 유입된 경로
취약한 코드는 요청의 Host 헤더를 읽고, 그 값이 루프백 주소와 일치하면 해당 요청을 로컬 머신에서 온 것으로 처리하는 단일 함수에 존재합니다.
샌드박스 내부에서 코드를 실행할 수 있는 공격자는 정교한 페이로드가 필요하지 않습니다. Host: 127.0.0.1이 포함된 HTTP 요청 하나만 보내면, 백엔드는 해당 호출이 호스트 자체에서 시작된 것으로 간주하여 모든 보안 프롬프트, 속도 제한(rate-limit) 체크 및 명령 검증 단계를 건너뜁니다. 결과적으로 추가적인 상호작용 없이 제한 없는 명령 실행이 가능해집니다.
헤더를 신뢰하는 것이 위험한 이유
헤더는 호출자가 제공하는 평문 문자열입니다. 필드 이름이 Host, X-Forwarded-For 또는 임의의 이름이든 관계없이, 클라이언트는 원하는 어떤 값으로든 설정할 수 있습니다. 연결이 실제로 어디에서 왔는지에 대한 유일하고 신뢰할 수 있는 정보원은 전송 계층(transport layer)입니다. 즉, TCP 핸드셰이크가 완료될 때 운영 체제가 기록하는 소켓의 소스 IP 주소입니다.
애플리케이션이 알려진 올바르게 구성된 프록시가 헤더를 삽입했는지 확인하지 않고 헤더를 신뢰하기로 결정하면, 공격자에게 왕국의 열쇠를 넘겨주는 꼴이 됩니다. DeepSeek Harness 버그는 이러한 실수에 대한 교과서적인 사례입니다.
실제 사례: shell.online 예시
웹 기반 터미널을 제공하는 오픈 소스 shell.online 프로젝트는 최근 동일한 함정을 문서화했습니다. 이 프로젝트는 TRUST_PROXY라는 구성 플래그를 사용합니다:
- TRUST_PROXY = 0 – 앱이 X-Forwarded-For 헤더를 무시하고 소켓의 원격 주소에 의존합니다. 이를 통해 클라이언트가 IP 주소를 위조하여 속도 제한을 회피하거나 신뢰할 수 있는 사용자로 위장하는 것을 방지합니다.
- TRUST_PROXY = 1 – 앱이 X-Forwarded-For 헤더를 클라이언트의 신원(identity)으로 신뢰합니다. 만약 서비스가 이 헤더를 정제(sanitise)하는 실제 프록시 뒤에 있지 않다면, 공격자는 매 요청마다 새로운 IP 주소를 제공하여 IP당 스로틀링(throttling)을 효과적으로 초기화할 수 있습니다.
DeepSeek 버그는 이 시나리오와 유사합니다. 코드는 프록시가 설정한 것처럼 Host를 신뢰했지만, 실제로는 서비스에 직접 접근할 수 있었습니다.
개발자가 지금 해야 할 일
- 클라이언트가 제공하는 헤더를 읽는 모든 곳을 감사하십시오. 어떤 헤더를 권한 있는 것으로 취급하는지(예: Host, X-Forwarded-For, X-Real-IP) 식별하고, 해당 헤더가 애플리케이션에 도달하기 전에 신뢰할 수 있는 프록시가 이를 반드시 재작성(rewrite)하는지 확인하십시오.
- 가능한 한 보안 결정을 소켓 주소와 연결하십시오. 인증, 속도 제한 및 액세스 제어 확인에는 OS가 제공하는 소스 IP를 사용하십시오.
- 서비스 앞에 올바르게 구성된 리버스 프록시가 있는 경우에만 프록시 신뢰 플래그를 활성화하십시오. 앱을 직접 실행하는 경우에는 해당 플래그를 비활성 상태로 유지하십시오.
- 프로젝트의 README 또는 배포 가이드에 필요한 배포 토폴로지(topology)를 문서화하십시오. 이를 통해 셀프 호스팅을 하는 사용자가 프록시 신뢰 요구 사항을 알 수 있도록 합니다.
- 정적 분석 또는 코드 리뷰 도구를 실행하십시오. 프록시 검증 로직 없이 보안 결정을 위해 헤더를 직접 사용하는 경우를 찾아내는 도구를 활용하십시오.
향후 주목할 점
셀프 호스팅 웹 서비스를 제공하는 커뮤니티는 이번 사건 이후 자체적인 프록시 신뢰 설정을 재검토할 가능성이 높습니다.
핵심 교훈은 명확합니다. 인터넷상의 누구나 작성할 수 있는 텍스트 조각이 시스템의 보안 태세를 결정하게 두지 마십시오. 요청 계층(request layer)이 아닌 네트워크 계층(network layer)을 신뢰하십시오.
