flawopen.com/Teardowns/cve-2026-105752-vllm-harmony-cache-salt-omission
CVE-2026-105752: vLLM의 cache_salt 누락
vLLM Responses의 GPT-OSS 도구 후속 처리는 cache_salt를 누락해 salt 없는 prefix-cache 네임스페이스를 사용할 수 있었습니다. vLLM 0.30.0 이상으로 업데이트하고 모든 후속 처리에서 테넌트별 salt를 유지하세요.[1], [5]
고객별 문서가 전용 색상표가 붙은 사물함에 있다고 상상해 보세요. 첫 요청에는 올바른 표가 붙지만 도구가 다음 단계를 위해 문서를 돌려줄 때 표가 빠집니다. 공유 선반은 캐시 적중으로 추측한 페이지 묶음의 존재를 알릴 수 있지만 페이지 자체를 주지는 않습니다.[1]
핵심 개념 및 용어
Prefix caching- 같은 접두부의 모델 키/값 블록을 재사용하는 방식.[6]
cache_salt- 서로 다른 salt의 캐시를 분리하도록 첫 블록 해시에 섞는 값.[6]
Harmony continuation- 도구 호출 뒤를 포함해 Harmony 응답 후 구성되는 다음 모델 입력.[1]
Membership oracle- 추측한 접두부의 존재를 알리지만 내용은 공개하지 않는 신호.[1]
CWE-524- 민감 정보가 든 캐시의 사용; 권고의 주요 분류.[1]
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-524
근본 원인 분석 (Root Cause)
vLLM 권고는 POST /v1/responses의 GPT-OSS Harmony 경로를 설명합니다. 최초 입력은 request.cache_salt를 tokens_input에 전달했지만 내장 또는 MCP 도구 호출 후 후속 처리는 salt 없이 tokens_input(token_ids)를 사용했습니다. helper는 salt를 전달받아야 저장합니다. 자동 prefix caching을 쓰는 공유 배포에서 후속 처리는 salt 없는 네임스페이스를 사용했습니다. 권고는 0.30.0 미만을 열거하고 0.25.1에서 확인했으며 더 낮은 경계는 확정되지 않았다고 밝힙니다. 결과는 cached_tokens_per_turn을 통한 캐시 구성원 신호이지 임의 프롬프트의 직접 공개가 아닙니다. CWE-200도 영향 분류로 제시되지만 여기서는 CWE-524만 주요 약점으로 사용합니다.[1], [3], [4]
단계별 공격 실행 흐름
공유 서비스가 전제 조건을 충족한다
영향 버전, GPT-OSS Harmony Responses, prefix caching, 도구가 필요하며 피해 요청은 cache_salt를 설정하고 후속 처리에 도달해야 합니다.[1]
첫 engine input에는 salt가 들어간다
첫 tokens_input 호출에는 request.cache_salt가 포함되어 접두부가 호출자의 salt 적용 네임스페이스에 들어갑니다.[1]
도구 후속 처리에서 salt가 빠진다
도구 결과 뒤 후속 처리는 원래 salt 없이 tokens_input(token_ids)를 호출해 공유된 salt 없는 영역에 들어갈 수 있습니다.[1]
캐시 수치가 구성원 여부를 드러낼 수 있다
다른 테넌트가 접두부를 재구성하면 cached_tokens_per_turn으로 존재를 추론할 수 있지만 임의 프롬프트 텍스트를 얻지는 못합니다.[1]
소스 코드 비교: 취약한 구현 vs 보안 패치
vLLM 권고는 POST /v1/responses의 GPT-OSS Harmony 경로를 설명합니다. 최초 입력은 request.cache_salt를 tokens_input에 전달했지만 내장 또는 MCP 도구 호출 후 후속 처리는 salt 없이 tokens_input(token_ids)를 사용했습니다. helper는 salt를 전달받아야 저장합니다. 자동 prefix caching을 쓰는 공유 배포에서 후속 처리는 salt 없는 네임스페이스를 사용했습니다. 권고는 0.30.0 미만을 열거하고 0.25.1에서 확인했으며 더 낮은 경계는 확정되지 않았다고 밝힙니다. 결과는 cached_tokens_per_turn을 통한 캐시 구성원 신호이지 임의 프롬프트의 직접 공개가 아닙니다. CWE-200도 영향 분류로 제시되지만 여기서는 CWE-524만 주요 약점으로 사용합니다. Upstream excerpts, not a literal line-by-line diff.[1], [3], [4], [7]
소스 코드 발췌: vLLM Responses Harmony renderer (서로 다른 리비전 발췌)
# 초기 요청 경로에는 salt가 적용됐지만 도구 호출 후 이어지는 경로에는 적용되지 않았습니다.
engine_input = tokens_input(token_ids, cache_salt=request.cache_salt)
# 도구 결과를 받은 뒤 이어지는 경로는 입력을 다음과 같이 다시 구성했습니다:
engine_input = tokens_input(token_ids)
# Harmony 렌더링 컨텍스트에서 요청 salt를 유지합니다.
cache_salt = cast(str | None, engine_input.get("cache_salt"))
engine_input = self.online_renderer.render_responses_harmony_messages(
context.messages,
cache_salt=cache_salt,
tok_params=tok_params,
)
# 렌더러는 엔진 입력을 만들 때마다 salt를 전달합니다.
engine_input = tokens_input(prompt["prompt_token_ids"], cache_salt=cache_salt)
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓vLLM 0.30.0 이상으로 업데이트하고 실행 중인 버전을 확인하세요.[1], [5]
- ✓신뢰할 수 있는 게이트웨이에서 예측 불가능한 cache_salt를 만들고 모든 요청과 후속 처리에 전달하세요.[6], [1]
- ✓도구 호출 뒤 모든 Harmony 후속 처리에서 salt가 유지되고 테넌트가 분리되는지 테스트하세요.[7]
- ✓엄격한 격리를 위해 프로세스 또는 배포 단위로 테넌트를 분리하세요.[6]
- ✓공유 기능을 점검하고 cached_tokens_per_turn 지표 접근을 제한하세요.[1]
- ✓위험을 접두부 추론으로 설명하고 임의 프롬프트 공개라고 표현하지 마세요.[1]