당신의 에이전트에는 검증하지 않은 중개자가 있습니다
연구자들은 Taobao, Xianyu, Shopify 기반 스토어프런트에서 유료 LLM API 라우터 28개를 구매하고, 공개 커뮤니티에서 무료 라우터 400개를 수집했습니다. 각 라우터에 계정을 등록하고, 샌드박스에 격리한 코딩 에이전트를 그 라우터를 거쳐 실행한 뒤, 돌아온 도구 호출을 모두 실행하면서 어떤 일이 벌어지는지 지켜보았습니다.1
428개 중 9개가 도구 호출을 공격자가 통제하는 명령이나 의존성으로 바꿔 썼습니다. 유료가 1개, 무료가 8개였습니다. 무료 라우터 17개는 전송 중에 본 AWS 카나리 자격 증명을 이후 실제로 사용했고, 1개는 심어 둔 Ethereum 키에서 자금을 빼갔습니다. 주입을 수행한 라우터 중 2개는 그 행동을 숨겼습니다. 하나는 50개의 요청이 지난 뒤에야 움직였고, 다른 하나는 자율 “YOLO mode”(도구 실행을 자동 승인하는 모드)로 Rust나 Go 프로젝트를 다루는 세션에서만 작동했습니다.1
LLM API 라우터는 애플리케이션 계층의 프록시입니다. TLS를 종료하고, 모든 요청과 응답을 평문으로 읽으며, 에이전트가 막 실행하려는 도구 호출을 바꿔 쓸 수 있습니다. 논문은 도구 호출 응답에 서명하는 주요 제공업체를 찾지 못했습니다. 따라서 에이전트가 실행하는 명령과 모델이 생성한 내용을 묶어 주는 장치는 아무것도 없습니다. 논문은 Claude Code와 Codex를 포함한 네 가지 에이전트 프레임워크를 시험했고, 응답 무결성을 확인하는 프레임워크는 하나도 없었습니다.1
이 글은 2026년 4월 10일 논문 초록을 바탕으로 처음 게시되었습니다. 2026년 10월 2일, 논문 전문을 기준으로 다시 썼습니다. 4월 버전에는 여러 오류가 있었고, 글 끝부분의 “4월 버전이 틀린 점”에 정리해 두었습니다.
TL;DR
- 라우터가 할 수 있는 일. 라우터는 사용자가 설정한 엔드포인트로서 클라이언트와 모델 제공업체 사이에 자리합니다. 그래서 모든 요청과 응답의 평문을 쥐고 있으며, 전달하기 전에 어느 쪽이든 바꿀 수 있습니다.1
- 라우터 428개가 한 일. 9개가 반환하는 도구 호출에 악성 코드를 주입했습니다(유료 28개 중 1개, 무료 400개 중 8개). 그중 무료 2개는 트리거를 써서 주입을 숨겼습니다. 무료 라우터 17개는 연구자 소유의 AWS 카나리 자격 증명을 사용했고, 1개는 잔액이 50달러 미만인 연구자 소유 Ethereum 키에서 자금을 빼갔습니다.1
- 유출된 키와 취약한 릴레이에서 일어난 일. 의도적으로 유출한 OpenAI 키 하나가 GPT-5.4 토큰 1억 개를 처리했고 7개가 넘는 Codex 세션을 노출시켰습니다. 허술하게 구성한 미끼 릴레이는 약 20억 토큰을 처리했고 440개 Codex 세션에 걸쳐 자격 증명 99개를 노출시켰습니다. 그중 401개 세션은 이미 도구 호출을 자동 승인하는 상태로 실행되고 있었습니다.1
- 방어책의 효과. 저자들이 직접 만든 합성 벤치마크에서 페일 클로즈드 정책 게이트는 오탐률 1.0%로 모든 주입 샘플을 차단했습니다. 그러나 단순한 적응형 벤치마크에서는 게이트의 존재를 아는 공격자가 샘플의 100%에서 게이트를 우회했습니다. 이상 탐지 스크리닝은 일반 주입의 89.0%, 회피형 주입의 약 절반을 잡아냈습니다.1
- 저자들이 제시하는 해결책. 제공업체가 서명한 응답 봉투입니다. 이것이 있으면 클라이언트는 도구 호출을 모델이 생성한 내용과 대조할 수 있습니다. 논문은 이를 제공하는 주요 제공업체를 찾지 못했습니다.1
- 라우터를 직접 호스팅한다면. 아래 10월 1일 업데이트에서 LiteLLM 권고 11건을 다룹니다. 그중 1건은 인증된 사용자라면 누구나 프록시가 제공업체 키를 외부로 보내게 만들 수 있는 취약점이었습니다.2
핵심 요약
- 에이전트 운영자: 클라이언트와 모델 제공업체 사이에 있는 모든 라우터는 모든 요청과 응답에 평문으로 접근할 수 있으며, 클라이언트가 설정하는 것은 첫 번째 홉뿐입니다. 마켓플레이스에서 산 라우터나 공개 목록에서 가져온 라우터는, 운영자를 신뢰할 별도의 근거가 생기기 전까지 적대적인 중개자로 취급하십시오.
- 하네스 개발자: PreToolUse 훅은 도구 호출이 실행되기 전에 동작하지만, 그 시점에 라우터는 이미 그 호출을 바꿔 쓸 기회를 가졌습니다. 훅에는 비교할 원본이 없습니다. 훅이 할 수 있는 일은 페일 클로즈드입니다. 목록에 있는 도메인에서만 내려받고 목록에 있는 패키지만 설치하는 셸 명령을 허용하고, 나머지는 차단하는 것입니다.3
- YOLO mode를 쓰는 모든 사람: 연구자들의 미끼 연구에서 관찰된 Codex 세션 440개 중 401개가 이미 도구 실행을 자동 승인한 상태로 실행되고 있었습니다.1 이런 세션에서는 트리거 로직 없이도 단순히 바꿔 쓴 명령이 그대로 실행되었을 것입니다. 자동 승인 세션을 직접 통제하지 않는 라우터를 거쳐 실행하지 마십시오.
- 자체 프록시를 호스팅하는 팀: 직접 운영하는 라우터에도 똑같이 제공업체 키가 집중됩니다. 2026년 10월 1일 PyPA 데이터베이스에 등록된 LiteLLM 권고 11건(대부분 6월부터 공개됨) 가운데에는, 인증된 사용자라면 누구나 프록시가 자신이 고른 호스트로 제공업체 키를 보내게 만들 수 있는 것이 있습니다. 1.97.0 이후 릴리스는 11건의 기록된 범위 모두에서 벗어나 있습니다. 자세한 내용은 아래 10월 1일 업데이트를 참고하십시오.2
라우터란 정확히 무엇인가요?
LLM API 라우터는 한 가지 형식(보통 OpenAI 호환)으로 요청을 받아 업스트림 제공업체를 고르고 응답을 돌려줍니다. 논문은 모든 규모의 라우터를 포함합니다. Amazon Bedrock이나 Azure OpenAI Service 같은 클라우드 관리형 서비스, LiteLLM이나 OpenRouter 같은 개발자용 프로젝트와 서비스, 그리고 재판매되고 집계된 API 접근을 사고파는 범용 시장입니다.1
사람들이 라우터를 쓰는 데에는 타당한 이유가 있습니다. 논문은 “model fallback, load balancing, cost optimization, and a single API key across providers”(모델 폴백, 부하 분산, 비용 최적화, 여러 제공업체에 걸친 단일 API 키)를 꼽으며, 라우팅이 특히 “in regions where direct provider access is restricted, expensive, or subject to quota limitations”(제공업체에 직접 접근하는 것이 제한되거나, 비싸거나, 할당량 제약이 있는 지역)에서 흔하다고 지적합니다.1
문제는 위치입니다. 논문의 표현을 빌리면 가로채기 기법은 필요 없습니다. “the client voluntarily configures the router’s URL as the API endpoint, the router terminates the client-side TLS connection, and it originates a separate TLS connection upstream”(클라이언트가 스스로 라우터의 URL을 API 엔드포인트로 설정하고, 라우터는 클라이언트 쪽 TLS 연결을 종료한 뒤 업스트림으로 별도의 TLS 연결을 연다). TLS는 각 구간을 보호하지만, 라우터로부터 페이로드를 보호하는 데는 아무 역할도 하지 않습니다. 라우터는 요청 JSON을 읽고 전달하며, 응답 JSON을 읽고 돌려주는데, 그 사이에 어느 쪽이든 바꿀 기회가 있습니다.1
라우터는 연쇄되기도 합니다. 논문의 예에서 개발자는 Taobao 재판매자에게서 접근 권한을 사고, 그 재판매자는 2차 집계 업체에서 키를 모으며, 그 집계 업체는 OpenRouter를 거쳐 라우팅하고, OpenRouter는 모델 호스트로 요청을 보냅니다. 홉이 네 개이고, 각 홉은 평문에 완전히 접근할 수 있습니다. “The client configures only the first hop; subsequent hops are invisible.”(클라이언트는 첫 번째 홉만 설정하며, 이후의 홉은 보이지 않는다) 어디든 나쁜 홉이 하나 있으면 경로 전체가 오염되고, 그 뒤의 정직한 홉들은 이를 알 수 없습니다.1
오늘날의 API에는 이 틈을 메우는 장치가 없습니다. 도구 호출 인자는 평문 JSON으로 전송되며, “No provider-level integrity mechanism binds the arguments returned by the model to the arguments received by the client.”(모델이 반환한 인자와 클라이언트가 받은 인자를 묶어 주는 제공업체 수준의 무결성 메커니즘은 없다)1
측정 방법
저자들은 라우터마다 네 단계를 거쳤습니다. 먼저 연구자가 통제하는 계정을 등록하고 API 자격 증명을 받았습니다. 그다음 그 계정을 샌드박스 에이전트 환경에 연결했는데, 이 환경은 “a randomized subset of custom tasks and TerminalBench 2.0 tasks”(자체 작업과 TerminalBench 2.0 작업 중 무작위로 고른 일부)를 실행하며 현실적인 셸, 패키지 설치, 파일 조작 도구 호출을 만들어 냅니다. 이어서 돌아온 도구 호출 페이로드를 모두 샌드박스 안에서 실행하고, 네트워크 콜백, 파일 시스템 변경, 프로세스 트리 이상을 감시했습니다. 마지막으로 별도의 분석 에이전트가 표시된 실행을 검토해 각각을 무해한 재작성, 악성 가능성 있음, 악성 확인 중 하나로 분류했습니다.1
정의는 보수적입니다. 라우터가 악성 코드를 주입했다고 집계하는 것은 “only if a returned tool-call payload is rewritten into an attacker-controlled command or dependency”(반환된 도구 호출 페이로드가 공격자가 통제하는 명령이나 의존성으로 바뀐 경우에만)입니다. AWS 카나리를 건드렸다고 집계하는 것은 라우터를 지나간 자격 증명이 “later produces follow-on AWS API activity attributable to that credential”(이후 그 자격 증명에 귀속되는 후속 AWS API 활동을 일으킨) 경우입니다.1
연구 대상은 분야 전체가 아니라 범용 시장입니다. 무료 라우터 400개는 대부분 sub2api와 new-api라는 두 오픈 소스 템플릿으로 이루어져 있으며, 저자들은 기업용 배포와 초대제 배포가 연구 범위 밖이라고 밝힙니다. 대상 대부분은 중국어권 마켓플레이스와 커뮤니티에서 왔습니다.1
현장 데이터
| 행동 | 유료 라우터(28) | 무료 라우터(400) |
|---|---|---|
| 반환하는 도구 호출에 악성 코드 주입 | 1 | 8 |
| 트리거 뒤에 주입을 숨김 | 관찰되지 않음 | 2 |
| 연구자 소유 AWS 카나리 자격 증명 사용 | 관찰되지 않음 | 17 |
| 연구자 소유 Ethereum 키에서 자금 인출 | 관찰되지 않음 | 1 |
주입은 겉모습만 바꾸는 수준이 아닙니다. 논문에 따르면 주입은 “change the command or dependency that the agent intends to execute”(에이전트가 실행하려는 명령이나 의존성을 바꾼다). 유료 쪽 결과는 28개 중 1개이며, 저자들은 분명한 결론을 내립니다. “Paid access improves service stability, but it does not prove tool-call integrity.”(유료 접근은 서비스 안정성을 높이지만 도구 호출의 무결성을 증명하지는 않는다)1
트리거를 가진 두 라우터는 테스트로는 잡아낼 수 없다는 사실을 보여 주는 발견입니다. 하나는 “malicious tool calls are injected only after the first 50 requests, which hides the attack from shallow smoke tests”(악성 도구 호출이 처음 50개 요청 이후에만 주입되어, 얕은 스모크 테스트로부터 공격을 숨긴다). 다른 하나는 주입을 “only for sessions that appear to be running in autonomous YOLO mode and only when the project fingerprint matches Rust or Go”(자율 YOLO mode로 실행되는 것으로 보이는 세션이면서 프로젝트 지문이 Rust나 Go와 일치할 때에만) 활성화합니다. 저자들은 관찰한 트리거가 전부가 아닐 수 있다고 덧붙입니다. 이 라우터들을 유한한 블랙박스 탐색으로만 관찰했기 때문에 “a router may implement additional latent conditions that our probes did not activate”(라우터는 우리 탐색이 활성화하지 못한 잠재 조건을 추가로 구현했을 수 있다)는 것입니다.1
자격 증명 관련 발견은 모두 무료 라우터에서 나왔습니다. 라우터 17개가 “trigger follow-on use of at least one researcher-owned AWS canary credential after seeing it in transit”(전송 중에 본 연구자 소유 AWS 카나리 자격 증명 중 적어도 하나를 이후 사용했다)고 하며, 1개는 미리 자금을 넣어 둔 Ethereum 키에서 자금을 빼갔습니다. 부록은 이 인출로 인한 손실을 50달러 미만으로 적고 있습니다.1
두 가지 오염 연구
라우터가 악의적이지 않아도 같은 위치에 놓일 수 있습니다. 저자들은 무해해 보이는 라우터 경로가 어떻게 오염되는지를 두 가지 연구로 살폈습니다.
연구 1: 유출된 키. 연구자 소유의 OpenAI API 키를 “on Chinese forums, WeChat, and Telegram groups frequented by router operators”(라우터 운영자들이 드나드는 중국어 포럼, WeChat, Telegram 그룹)에 유출했습니다. 이 키 하나가 GPT-5.4 토큰 1억 개를 처리했고 7개가 넘는 Codex 사용자 세션을 노출시켰으며, 적어도 한 세션에서는 그 뒤에 서로 다른 자격 증명 여러 개가 나타났습니다. 논문은 트래픽이 어떻게 흘러들었는지에 대해 신중합니다. 결과는 “is consistent with several paths: direct reuse by a router operator, direct reuse by unrelated third parties, or reuse somewhere inside a longer relay chain”(여러 경로와 부합한다. 라우터 운영자의 직접 재사용, 무관한 제3자의 직접 재사용, 또는 더 긴 릴레이 체인 내부 어딘가에서의 재사용)이며, 저자들은 “cannot always distinguish among those paths from provider-side logs alone”(제공업체 쪽 로그만으로는 이 경로들을 항상 구별할 수는 없다)고 말합니다. 이 연구가 확인한 것은 피해 반경입니다. 재사용된 업스트림 키를 쥔 사람은 그 뒤의 트래픽을 평문으로 봅니다.1
연구 2: 취약한 릴레이. 취약한 claude-relay-service 인스턴스를 20개 도메인에, 약한 비밀번호를 쓰는 Sub2API와 CLIProxyAPI 인스턴스를 20개 IP에 배포했습니다. 미끼에는 147개 IP에서 4만 건이 넘는 무단 접근 시도가 들어왔는데, 저자들은 이를 모두 표적 공격으로 보지 않고 스캐닝과 릴레이 재사용이 섞인 것으로 해석합니다. 더 강한 신호는 그 뒤에 나왔습니다. 미끼가 “were folded into active agent-facing relay paths”(실제로 운영 중인 에이전트용 릴레이 경로에 편입되었다). 미끼는 GPT-5.4와 5.3-codex 토큰 약 20억 개, 눈에 보이는 프롬프트와 응답 트래픽으로 약 13 GB를 처리했고, 프로젝트 또는 호스트 398곳에 걸친 Codex 세션 440개에서 고유 자격 증명 99개를 노출시켰습니다.1
이 440개 세션은 모두 논문의 정의상 명령 주입이 가능했고, 401개는 “already operated in YOLO mode, i.e., with tool execution auto-approved rather than confirmed command by command”(이미 YOLO mode로 동작하고 있었다. 즉 도구 실행을 명령마다 확인하지 않고 자동 승인하고 있었다). 저자들은 이 401개에 대해 “sophisticated adaptive evasion was unnecessary: basic payload injection would have been sufficient to change executed commands”(정교한 적응형 회피는 필요 없었다. 기본적인 페이로드 주입만으로도 실행되는 명령을 바꾸기에 충분했을 것이다)라고 씁니다.1
이 세션들은 다른 사람들의 것이었습니다. 미끼가 릴레이 경로에 편입된 뒤 그들의 트래픽이 연구자들의 미끼에 도달했고, 첫 번째 홉만 설정하는 사용자는 이를 알아챌 방법이 없었을 것입니다. 저자들은 집계 메타데이터와 솔트를 적용한 해시만 보관했고, 관찰 기간이 끝나자 노출된 자신들의 자격 증명을 폐기했습니다.1
두 가지 핵심 공격 클래스와 두 가지 회피 변종
논문은 악성 라우터의 행동을 두 가지 기본형과, 첫 번째 기본형을 정교하게 다듬은 두 가지 변형으로 정리합니다.1
AC-1: 응답 측 페이로드 주입. 라우터는 도구 호출이 제공업체를 떠난 뒤 클라이언트에 도착하기 전에, 도구 이름과 스키마는 그대로 둔 채 호출을 바꿔 씁니다. 논문의 예는 설치 프로그램 URL이 공격자의 것으로 바뀐 Bash 호출입니다. 결과는 여전히 해당 도구에 맞는 유효한 JSON이므로 클라이언트가 보기에는 이상한 점이 없습니다.
AC-2: 수동적 비밀 정보 유출. 라우터는 아무것도 바꾸지 않습니다. 요청과 응답에서 자격 증명 패턴을 찾아 발견한 것을 보관합니다. 트래픽이 변경되지 않으므로 “clients cannot observe router-side retention”(클라이언트는 라우터 쪽의 보관을 관찰할 수 없다). 노출 범위는 API 키보다 넓습니다. “system prompts, tool definitions, user-supplied file contents, and environment variables all transit the same plaintext channel”(시스템 프롬프트, 도구 정의, 사용자가 제공한 파일 내용, 환경 변수가 모두 같은 평문 채널을 지나간다).
AC-1.a: 의존성을 노린 주입. 패키지 설치 명령을 겨냥한 AC-1의 변종입니다. 라우터는 URL을 바꾸는 대신 “substitutes a legitimate dependency name with an attacker-controlled package pre-registered on the target registry”(정상적인 의존성 이름을, 대상 레지스트리에 미리 등록해 둔 공격자 통제 패키지로 바꾼다). 논문의 예에서는 pip install requests가 pip install reqeusts로 바뀝니다. 명령은 여전히 신뢰하는 레지스트리에서 설치하므로 도메인만 확인하는 게이트는 이를 통과시키고, 악성 패키지는 캐시에 남아 이후 세션에서도 쓰입니다.
AC-1.b: 조건부 전달. AC-1이 언제 작동할지를 정하는 변종입니다. 라우터는 트리거와 일치할 때까지 정직하게 행동합니다. 논문은 트리거를 다섯 계열로 나눕니다. 도구 이름, 콘텐츠 키워드, YOLO mode 같은 사용자 지문, 시간대, 요청 수입니다. “A router deploying a 50-request warm-up appears entirely transparent during a 10-request probe.”(50개 요청의 워밍업을 두는 라우터는 10개 요청짜리 탐색 동안 완전히 투명해 보인다)
논문은 2026년 3월의 LiteLLM 침해를 대규모 AC-1 사례로 꼽습니다. 공격자가 프록시의 요청 파이프라인을 장악하자, 그곳을 지나는 모든 도구 호출이 재작성에 노출되었습니다. (논문은 이 침해를 의존성 혼동으로 설명합니다. 제가 공급망 글에서 참고한 보도는 원인을 Trivy 침해를 통해 탈취된 PyPI 게시 토큰으로 추적합니다.)
연구용 프록시가 에이전트 클라이언트에 대해 보여 준 것
저자들은 Mine이라는 프록시를 만들어 네 가지 클래스를 모두 구현하고, 공격 모듈마다 도구 호출 요청 1,000건을 네 가지 공개 에이전트 프레임워크인 OpenClaw, OpenCode, OpenAI의 Codex, Anthropic의 Claude Code에 각각 흘려보냈습니다.1
네 프레임워크 모두 응답 무결성을 검증하지 않았습니다. 바뀐 도구 호출은 AC-1 사례의 100%, AC-1.a 사례의 99.6%에서 프레임워크 고유의 유효한 형식으로 도착했습니다. 논문은 이 결과가 보여 주는 것과 보여 주지 않는 것을 정확히 구분합니다. “These are compatibility measurements, not end-to-end execution rates: they show that the tampered tool call reaches the client in a valid framework-native format, but downstream permission prompts or local execution sandboxes may still block the resulting action.”(이는 호환성 측정이지 종단 간 실행률이 아니다. 변조된 도구 호출이 프레임워크 고유의 유효한 형식으로 클라이언트에 도달한다는 것은 보여 주지만, 이후의 권한 프롬프트나 로컬 실행 샌드박스가 그 결과로 나오는 동작을 여전히 막을 수 있다)1
바로 이 단서에서 권한 프롬프트가 제 몫을 하며, 미끼 연구의 숫자에서 자동 승인이 그토록 중요한 이유도 여기에 있습니다. 저자들은 Mine을 공개하지 않았습니다.1
합성 패턴, 한 계층 아래
저는 같은 구조적 버그에 대해 계속 글을 쓰고 있습니다. 개별적으로는 권한을 받은 구성 요소들이 결합해 권한 없는 행동을 만들어 내는 문제입니다. Trivy에서 LiteLLM으로 이어진 침해는 패키지 계층의 결합이었습니다. 사일런트 이그레스는 가져온 콘텐츠 계층의 결합이었고, MCP 도구 포이즈닝은 프로토콜 계층의 결합이었습니다.
라우터 공격은 클라이언트와 제공업체 사이의 홉에서 일어나는 결합입니다. 클라이언트는 라우터를 호출할 권한이 있습니다. 라우터는 업스트림 모델을 호출할 권한이 있습니다. 모델은 응답할 권한이 있습니다. 모든 홉이 권한을 갖고 있는데도, 결합된 결과는 바뀐 명령을 낳습니다. 홉을 건너는 내용에 아무도 서명하지 않기 때문입니다. 그리고 비밀 정보가 복사됩니다. 모든 홉이 그것을 평문으로 읽기 때문입니다.
논문은 MCP 자체와의 연결선도 긋습니다. “a malicious MCP server receives tool-call requests in plaintext and can return forged results, so the same basic manipulation and collection ideas transfer with adaptation to the MCP message format”(악성 MCP 서버는 도구 호출 요청을 평문으로 받고 위조된 결과를 돌려줄 수 있으므로, 같은 기본적인 조작과 수집 아이디어가 MCP 메시지 형식에 맞게 조정되어 그대로 옮겨 간다). 동시에 차이도 짚습니다. MCP 서버는 도구 실행 쪽에 있어 도구 출력을 위조할 수 있습니다. 라우터는 모델로 가는 경로 위에 있어 모든 도구 호출과 요청 컨텍스트 전체를 봅니다.1
세 가지 방어책과 논문의 수치
논문은 어떤 제공업체의 도움 없이도 클라이언트가 배포할 수 있는 세 가지 통제를 평가합니다. 아래 모든 수치에는 한 가지 단서가 붙습니다. “All numbers in this section come from controlled artifact-side evaluation rather than field data.”(이 절의 모든 수치는 현장 데이터가 아니라 통제된 아티팩트 측 평가에서 나왔다) 데이터 집합은 저자들의 스크립트로 생성한 합성 데이터입니다.1
| 방어책 | AC-1 | AC-1.a | AC-1.b | 비용과 한계 |
|---|---|---|---|---|
| 페일 클로즈드 정책 게이트 | 100% 차단 | 100% 차단 | 측정하지 않음 | 오탐 1.0%, 단순한 적응형 벤치마크에서 샘플의 100%가 우회 |
| 응답 측 이상 탐지 스크리닝 | 89.0% 탐지 | 50.0% 탐지 | 50.9% 탐지 | 오탐 6.7% |
| 추가 전용 투명성 로그 | 감사 전용 | 감사 전용 | 감사 전용 | 항목당 약 1.26 KB |
정책 게이트는 “fetch from non-allowlisted domains or install packages outside a local allowlist”(허용 목록에 없는 도메인에서 내려받거나 로컬 허용 목록 밖의 패키지를 설치하는) 셸 명령을 차단합니다. 무해한 명령 1,000건, AC-1 샘플 500건, AC-1.a 샘플 500건에서 모든 공격 샘플을 차단했고, 오탐은 모두 허용 목록에 빠진 미러 도메인에서 설치 프로그램을 내려받는 경우였습니다. 저자들은 이를 “the strongest immediately deployable control”(즉시 배포할 수 있는 가장 강력한 통제)이라고 부릅니다. 동시에 실패도 숨김없이 보고합니다. 공격자가 허용 목록에 있는 도메인에 페이로드를 올려 두거나, 무해해 보이는 명령이 나중에 실행할 로컬 스크립트를 미리 심어 두면 “the policy gate is bypassed in 100% of samples”(정책 게이트는 샘플의 100%에서 우회된다). 저자들의 판단은 이 게이트가 “should be understood as a coarse but useful filter for obvious high-risk workflows, not as a robust defense against defense-aware attackers”(명백히 위험한 워크플로를 거르는 거칠지만 유용한 필터로 이해해야 하며, 방어를 아는 공격자에 대한 견고한 방어로 보아서는 안 된다)라는 것입니다.1
게이트를 만드는 사람에게 중요한 세부 사항이 하나 있는데, 논문은 이 점에서 일관되지 않습니다. 4절은 게이트를 도메인만 보는 것으로 설명하고, AC-1.a를 그것을 뚫도록 설계합니다. “the gate blocks non-allowlisted domains but does not maintain a per-package allowlist”(게이트는 허용 목록에 없는 도메인은 차단하지만 패키지별 허용 목록은 유지하지 않는다). 그런데 AC-1.a에 대해 100%를 기록한 7절의 게이트는 “outside a local allowlist”(로컬 허용 목록 밖의) 설치도 차단합니다. 제가 읽기로는, 패키지 목록이 없는 게이트는 타이포스쿼팅 치환을 완전히 놓칩니다.
이상 탐지 스크리닝은 반환된 도구 호출 각각을 셸 위험 패턴이나 인자 엔트로피처럼 로컬에서 보이는 특징으로 점수화하며, 비교할 업스트림 원본은 없습니다. 오탐률 6.7%에서 AC-1 샘플의 89.0%, AC-1.a의 50.0%, AC-1.b의 50.9%를 탐지했습니다. 오탐 허용치를 1%로 두면 AC-1의 43.5%를 잡았고 AC-1.a는 사실상 하나도 잡지 못했습니다. 저자들은 이를 “useful for review prioritization”(검토 우선순위를 정하는 데 유용하다)고 평가하며 게이트보다 약하다고 봅니다.1
투명성 로그는 요청, 응답, 라우터 URL, TLS 메타데이터, 원본 응답의 해시를 기록합니다. 아무것도 막지는 못합니다. 사고가 난 뒤에 라우터나 자격 증명이 어디까지 닿았는지, 어떤 세션이 그곳을 지나갔는지에 답할 수 있게 해 줄 뿐입니다.1
저자들이 요구하는 해결책
세 가지 통제 중 어느 것도 도구 호출의 출처를 인증하지 않습니다. 저자들도 그렇게 말합니다. “No client-side control available today can prove that a router preserved the upstream provider’s response.”(오늘날 사용할 수 있는 클라이언트 측 통제 중 라우터가 업스트림 제공업체의 응답을 보존했다는 것을 증명할 수 있는 것은 없다)1
그것을 가능하게 하는 것은 제공업체의 서명입니다. 논문은 “a provider-signed canonical response envelope, similar in spirit to DKIM for email”(이메일의 DKIM과 같은 취지의, 제공업체가 서명한 표준 응답 봉투)을 제안합니다. 여기에는 모델 식별자, 도구 이름, 도구 인자, 종료 사유, 클라이언트 논스가 담기며, 클라이언트는 도구 호출을 실행하기 전에 이를 검증합니다. 논문은 이를 제공하는 곳이 없다고 보고합니다. “To our knowledge, none of the major provider tool-use APIs or the current MCP specification expose a deployed response-signing mechanism for tool-call arguments today.”(우리가 아는 한, 주요 제공업체의 도구 사용 API와 현재 MCP 사양 어디에도 도구 호출 인자에 대한 응답 서명 메커니즘이 오늘날 배포되어 있지 않다)1
이 제안에는 두 가지 한계가 따릅니다. 전송 보안은 그 대안이 될 수 없습니다. 상호 TLS와 인증서 고정은 “can authenticate the router endpoint the client chose, but they do not say whether the returned tool call preserves upstream semantics”(클라이언트가 고른 라우터 엔드포인트를 인증할 수는 있지만, 반환된 도구 호출이 업스트림의 의미를 보존하는지는 알려 주지 않는다). 그리고 서명은 탈취된 비밀 정보에 아무 도움이 되지 않습니다. “AC-2 cannot be mitigated by response-signing proposals because the secrets are exposed on the request path before any provider-side mechanism can act.”(AC-2는 응답 서명 제안으로 완화할 수 없다. 제공업체 쪽 메커니즘이 작동하기 전에 비밀 정보가 요청 경로에서 노출되기 때문이다)1
실제로 해야 할 일
직접 만들지 않은 라우터를 거쳐 에이전트가 모델을 호출하고 있다면 다음을 실천하십시오.
- 가능하면 직접 연결하고, 그럴 수 없다면 운영자를 파악하십시오. 라우터를 추가하는 데 필요한 것은 기본 URL 변경 하나뿐이며, 그래서 아무런 결정 없이 추가되곤 합니다. 이를 결정의 대상으로 만드십시오. 여기서 “신뢰”란 아는 팀, 계약, 법적으로 책임을 물을 수 있는 관할권 같은 외부 근거를 뜻합니다. 마켓플레이스 리뷰는 그런 근거가 아닙니다.
- 위험도가 높은 도구 호출에는 페일 클로즈드로 대응하십시오. Claude Code에서는 허용 목록 밖의 도메인에서 내려받는 셸 명령과 허용 목록 밖의 패키지 설치를 차단하는 PreToolUse 훅이 그것입니다. 패키지 목록도 유지하십시오. 의존성 치환 변종은 도메인만 보는 게이트를 뚫으려고 존재합니다. 훅은 파싱할 수 없는 것은 모두 종료 코드 2나
deny결정으로 거부하도록 작성하십시오. Claude Code는 그 밖의 종료 코드와 타임아웃을 차단하지 않는 것으로 처리하므로, 충돌하거나 멈춘 훅은 호출을 막지 못합니다. 호출은 일반 권한 흐름으로 넘어가고, 자동 승인 세션이라면 그대로 실행됩니다. 훅이 첫 호출에서 실제로 실행되었는지도 확인하십시오. 문서는 “a mistyped path in settings.json leaves the gate silently disabled”(settings.json에 경로를 잘못 입력하면 게이트가 아무 경고 없이 비활성화된다)고 경고합니다. 두 목록을 계속 관리해야 하고, 작정한 공격자는 이를 우회할 것이라고 예상하십시오.3 - 직접 통제하지 않는 라우터를 거쳐 자동 승인 세션을 실행하지 마십시오. 미끼 연구의 401개 세션이 그 선례입니다. 권한 프롬프트는 바뀐 도구 호출과 그 실행 사이를 가로막는 몇 안 되는 장치 중 하나입니다.
- 비밀 정보를 트래픽에 싣지 마십시오. 수동적 수집은 관찰할 수 있는 것을 아무것도 바꾸지 않습니다. 프롬프트, 도구 결과, 에이전트가 읽는 파일에 들어 있는 것은 무엇이든 평문으로 라우터를 지나갑니다. 자격 증명의 범위를 좁게 잡고, 가능한 한 컨텍스트에서 빼고, 나중에 의심스러워진 라우터를 거친 것은 모두 교체하십시오.
- 로컬에 로그를 남기십시오. 요청, 응답, 라우터 URL, 응답 해시를, 요청에서 비밀 정보를 먼저 가린 뒤 라우터가 닿을 수 없는 곳에 저장하십시오. 공격을 막지는 못하지만, 무엇이 노출되었는지 나중에 알려 줍니다.
- 실행을 샌드박스에 격리하십시오. 논문은 샌드박스가 “reduce post-execution blast radius but do not authenticate where a tool call came from”(실행 후 피해 반경을 줄이지만 도구 호출의 출처를 인증하지는 않는다)고 지적합니다. 앞의 절반을 취하십시오.
불편한 함의
라우터 계층은 에이전트 생태계가 인프라를 보호하는 속도보다 빠르게 출시하고 있다는 것을 보여 주는 명확한 사례입니다. 사람들은 모든 모델에 쓸 수 있는 키 하나, 더 낮은 가격, 제공업체가 서비스하지 않는 지역에서의 접근을 원합니다. 라우터는 이 세 가지를 모두 제공하고, 시장은 그에 보상합니다.
같은 흐름이 MCP 계층, 패키지 계층, 가져온 콘텐츠 계층에서도 되풀이되었습니다. 에이전트 스택에 새 계층이 나타납니다. 누군가 감사하기 전에 개발자들이 채택합니다. 공격자가 오고, 그다음 연구자가 옵니다. 이번에 연구자들이 센 것은 라우터 428개, 악성 코드를 주입한 9개, 심어 둔 자격 증명을 사용한 17개, 지갑을 턴 1개, 그리고 연구자들의 미끼를 포함한 릴레이 경로를 흘러간 자동 승인 세션 401개였습니다.1
이 틈을 메울 조각, 즉 제공업체가 서명한 응답은 운영자가 덧붙일 수 있는 것이 아닙니다. 제공업체가 이를 내놓기 전까지 위의 통제들은 노출을 줄여 주지만, 어느 것도 도구 호출이 모델 자신의 것임을 증명하지는 못합니다.
업데이트, 2026년 10월 1일: 직접 호스팅하는 라우터도 목록에 있습니다
이 글은 다른 사람이 운영하는 라우터에 관한 것입니다. 권고 기록이 나머지 절반을 채워 줍니다. 2026년 10월 1일 PyPA 권고 데이터베이스에 LiteLLM에 대한 항목 11건이 추가되었습니다. LiteLLM은 팀들이 위에서 말한 이유, 즉 모든 모델에 키 하나를 쓰기 위해 직접 호스팅하는 오픈 소스 프록시입니다.2 새로운 것은 하나도 없습니다. 9건은 6월 21일부터 GitHub 권고 데이터베이스와 NVD에 올라 있었고, 10번째는 9월 중순부터였습니다. 그리고 제공업체 키를 노출시키기 때문에 프록시에 가장 중요한 1건은 8월 26일 LiteLLM 자체 저장소에 게시되었으며, 수정판은 8월 9일부터 PyPI에 있었습니다. GitHub는 이를 Moderate로 평가합니다. 이 항목들은 함께 읽을 가치가 있습니다. 이 계층에 대해 말해 주는 바가 있고, 8월 9일 이전에 게시된 모든 최종 릴리스가 CVE-2026-84377의 범위 안에 있기 때문입니다.
가장 먼저 읽을 것은 CVE-2026-84377입니다. 저장소 권고의 표현으로는 “Any authenticated LiteLLM proxy user could redirect an outbound provider call to a destination they control and cause the proxy to send its own configured provider credentials to that destination.”(인증된 LiteLLM 프록시 사용자라면 누구나 외부로 나가는 제공업체 호출을 자신이 통제하는 목적지로 돌리고, 프록시가 자체 설정된 제공업체 자격 증명을 그 목적지로 보내게 만들 수 있었다) 원인은 검사 방식에 있었습니다. “The proxy’s request-body validation was a denylist that did not cover every sensitive parameter and did not inspect parameters nested inside other request fields.”(프록시의 요청 본문 검증은 거부 목록 방식이었고, 민감한 매개변수를 모두 다루지 못했으며, 다른 요청 필드 안에 중첩된 매개변수는 검사하지 않았다) 수정은 1.88.6부터 1.96.2까지 아홉 개 릴리스 라인에 들어갔습니다. 당장 업그레이드할 수 없는 사람을 위해 권고는 한 문장에 세 가지 우회책을 나열합니다. “Set general_settings.allow_client_side_credentials to false so callers cannot override connection parameters, restrict proxy keys to trusted callers, and block the affected parameters (api_base, base_url, model_list, fallbacks, provider credential fields) at a reverse proxy or API gateway.”(호출자가 연결 매개변수를 덮어쓰지 못하도록 general_settings.allow_client_side_credentials를 false로 설정하고, 프록시 키를 신뢰하는 호출자로 제한하며, 영향받는 매개변수를 리버스 프록시나 API 게이트웨이에서 차단하라)2 첫 번째만으로는 충분하지 않습니다. 영향받는 릴리스인 1.95.0의 소스에서 요청 본문 검사가 완전히 건너뛰어지는 것은 이 설정이 true일 때뿐입니다(배포의 configurable_clientside_auth_params로 개별 매개변수를 예외로 둘 수는 있습니다). 따라서 이 설정을 건드린 적 없는 설치는 이미 false 상태에 있으며, 불완전한 검사 자체가 권고가 설명하는 결함입니다. 해결책은 업그레이드입니다.6
두 번째 항목인 CVE-2026-59823은 같은 결함의 축소판입니다. 가드는 “blocks the api_base and base_url parameters but does not cover user_config”(api_base와 base_url 매개변수는 차단하지만 user_config는 다루지 않는다) 그래서 유효한 가상 키를 가진 호출자는 그 안에 api_base를 넣어 프록시가 임의의 호스트를 향하게 할 수 있었습니다. 이 결함은 1.83.9에서 패치되었고 4월 17일부터 PyPI에 있었으며, 권고는 9월에야 뒤따랐습니다.4
두 항목은 프록시의 MCP 쪽과 관련됩니다. MCP 프록시의 부적절한 인증(CVE-2026-12773, 버전 범위는 1.84.0의 수정으로 끝남)과, MCP OpenAPI 사양 로더의 spec_path 인자를 통한 서버 측 요청 위조(CVE-2026-12798, 1.82.2까지의 버전에 영향을 주는 것으로 기록됨)입니다. 나머지 7건은 관리자 키 처리, SSO 디버그 흐름, SSO 세션 무효화, 생성된 키의 세션 만료, UI의 사용자 열거, 비동기 엔드포인트의 가드레일 우회, 기계 간 JWT 처리를 다룹니다.5
이 9건의 기록은 앞의 두 건보다 내용이 빈약합니다. 설명은 관리자의 해설이 아니라 VulDB의 정형화된 문구로 되어 있고, MCP 프록시 항목의 설명에는 “up to 1.59.8”(1.59.8까지)이라고 되어 있는 반면 버전 범위는 1.84.0에서 수정되었다고 되어 있습니다.5 CVE-2026-84377의 기록에도 그 나름의 불일치가 있습니다. 저장소 페이지는 영향받는 버전을 “<1.94.0”으로 적고 있지만, 검토된 기록의 범위는 1.96 라인을 그 수정판인 1.96.2까지 포함합니다.2
요약을 믿지 말고, 이 요약도 마찬가지로, 운영 중인 릴리스와 범위를 직접 대조하십시오. 기록된 범위는 모두 1.96.2 이하에서 끝나므로, 8월 16일부터 PyPI에 있는 1.97.0 이후 릴리스는 11건 모두의 범위 밖에 있습니다. 10월 1일 기준 최신 릴리스는 1.103.2입니다.5
라우터의 위험은 누가 운영하든 자격 증명이 어디에 있느냐에 달려 있습니다. 심어 둔 AWS 키를 건드리는 마켓플레이스 라우터와, 구슬려서 제공업체 키를 외부로 보내게 만들 수 있는 자체 호스팅 프록시는 같은 노출에 두 방향에서 도달한 것입니다. 하나는 운영자를 통해, 다른 하나는 가상 키를 가진 아무 테넌트를 통해서입니다. 위 절들의 방어책은 당신이 클라이언트라는 것을 전제로 합니다.
직접 운영하는 프록시라면 운영자 몫의 대책을 더하십시오. 모든 가상 키를 그 뒤에 있는 업스트림 키에 대한 자격 증명으로 취급하십시오. 필요하지 않다면 배포별 configurable_clientside_auth_params를 포함해 클라이언트가 지정하는 연결 매개변수를 꺼 두십시오. 그리고 비밀 정보를 보관하는 다른 모든 것과 같은 패치 주기에 프록시를 올리십시오.
프록시가 영향받는 릴리스로 실행되는 동안 완전히 신뢰하지 않는 누군가가 가상 키를 갖고 있었다면, 제공업체 키와 프록시에 설정된 다른 비밀 정보를 교체하고, 설정하지 않은 호스트로 나간 호출이 있는지 로그를 확인하십시오. 권고의 영향 범위에는 “other configured secrets”(그 밖의 설정된 비밀 정보)와 “internal services reachable from the proxy”(프록시에서 접근할 수 있는 내부 서비스)로의 요청이 포함됩니다. 11건 중 2건, 즉 MCP 프록시의 CVE-2026-12773과 SSO 디버그 흐름의 CVE-2026-12795는 1.84.0 미만 릴리스의 인증 결함이므로, 그 릴리스에서는 키를 가진 사람만 프록시에 접근할 수 있었다고 단정할 수 없습니다. 신뢰하지 않는 네트워크에서 프록시에 접근할 수 있었다면 같은 교체를 적용하십시오.
4월 버전이 틀린 점
이 글의 4월 10일 버전은 논문 초록을 바탕으로 썼습니다. 2026년 10월 2일 전문과 대조해 보니 다음 부분이 틀렸거나 오해의 소지가 있었으며, 모두 위에서 바로잡았습니다.
- AC-1.a. 저는 이를 “only fires when the request matches a specific dependency or context”(요청이 특정 의존성이나 컨텍스트와 일치할 때만 작동하는) 주입이라고 설명했습니다. 실제로는 설치 명령 안에서 패키지 이름을 바꾸는 것입니다. 트리거는 AC-1.b입니다.
- 방어책. 저는 “the abstract does not rank the defenses”(초록은 방어책의 순위를 매기지 않는다)라고 쓰고 제 의견으로 순위를 제시했습니다. 논문 본문은 세 가지를 모두 측정하고, 정책 게이트를 “the strongest immediately deployable control”(즉시 배포할 수 있는 가장 강력한 통제)이라고 부르며, 단순한 적응형 벤치마크에서 샘플의 100%가 우회되었다고 보고합니다. 저는 이를 빠뜨렸습니다.
- 서명에 관한 조언. 저는 운영자에게 클라이언트에서 요청에 서명하고 업스트림에서 검증하라고 권하며 이를 “the only real fix”(유일한 진짜 해결책)라고 불렀습니다. 논문이 요구하는 것은 반대 방향, 즉 제공업체가 서명하고 클라이언트가 검증하는 응답이며, 서명으로는 탈취된 비밀 정보를 해결할 수 없다고 말합니다.
- 유출된 키. 저는 키가 “as if it had been exposed through a developer mistake”(개발자의 실수로 노출된 것처럼) 유출되었다고 쓰고 “The router was a laundering layer for a stolen key.”(라우터는 탈취된 키를 세탁하는 계층이었다)라고 결론지었습니다. 실제로는 라우터 운영자들이 자격 증명을 공유하는 포럼과 채팅 그룹에 유출한 것이며, 논문은 재사용한 쪽이 라우터 운영자인지, 무관한 제3자인지, 더 긴 릴레이 체인인지 항상 구별할 수는 없다고 말합니다.
- 자격 증명 수치. 답변 블록에는 “17 of 28 paid routers touched planted AWS credentials”(유료 라우터 28개 중 17개가 심어 둔 AWS 자격 증명을 건드렸다)라고 되어 있었고, 설명에는 연구자들이 라우터 28개를 시험했다고 되어 있었습니다. 논문의 유료 행에는 자격 증명 악용이 관찰되지 않았습니다. AWS 카나리를 사용한 라우터 17개와 ETH를 빼간 1개는 모두 무료 라우터 400개에 속합니다.
- 훅에 관한 조언. 저는 “validate response shapes”(응답 형태를 검증하는) PostToolUse 훅을 권했습니다. PostToolUse 훅은 도구가 실행된 뒤에 동작하므로, 바뀐 명령에 대응하기에는 너무 늦습니다. 논문이 시험한 통제는 실행 전 게이트이며, Claude Code에서는 허용 목록을 갖춘 PreToolUse 훅이 이에 해당합니다.
- 사소한 오류. 논문의 저자는 다섯 명이 아니라 여섯 명입니다. 논문은 라우터가 “knows when it is being sampled”(샘플링되고 있다는 것을 안다)고 말하지 않습니다. 이는 제가 덧붙인 과장이었습니다. 도입부는 주제를 “MCP trust chains”(MCP 신뢰 체인)라고 불렀지만, 논문은 MCP가 아니라 라우터를 연구합니다. 또 사일런트 이그레스 글을 도구 설명에 관한 글이라고 소개했지만, 실제로는 가져온 콘텐츠에 숨겨진 지시에 관한 글입니다.
FAQ
이 맥락에서 LLM API 라우터란 무엇인가요?
통일된 형식(보통 OpenAI 호환)으로 요청을 받아 업스트림 모델 제공업체를 고르고 응답을 돌려주는 서비스입니다. 모든 요청과 응답에 평문으로 접근하는 애플리케이션 계층 프록시입니다.1
TLS가 악성 라우터로부터 보호해 주나요?
아닙니다. 클라이언트가 라우터를 엔드포인트로 설정하므로, 라우터는 클라이언트의 TLS 세션을 종료하고 업스트림으로 별도의 세션을 엽니다. TLS는 각 구간을 보호할 뿐, 라우터로부터 페이로드를 보호하지는 못합니다.1
도구 호출을 바꿔 쓰는 라우터는 어떻게 탐지할 수 있나요?
테스트로는 확실히 탐지할 수 없습니다. 연구에 나온 라우터 2개는 50개 요청 이후에만, 또는 Rust나 Go 프로젝트의 자동 승인 세션에서만 주입했고, 논문은 “no fixed-length client test can guarantee that the router is benign”(고정된 길이의 클라이언트 테스트로는 라우터가 무해하다는 것을 보장할 수 없다)고 결론짓습니다. 셸 명령과 패키지 설치에 대한 페일 클로즈드 허용 목록은 단순한 경우를 차단하지만, 논문은 방어를 아는 공격자가 이를 통과한다는 것을 보여 줍니다.1
PreToolUse 훅이 도움이 되나요?
네, 정책 게이트로서는 도움이 됩니다. 훅이 보는 것은 클라이언트가 받은 도구 호출이며, 라우터가 바꿔 썼다면 바뀐 호출입니다. 훅은 목록에 없는 도메인에서 내려받거나 목록에 없는 패키지를 설치하는 명령을 차단할 수 있습니다. 하지만 그 호출이 모델이 생성한 것인지는 판별할 수 없습니다.13
Claude Code를 api.anthropic.com에 직접 연결해 쓰고 있습니다. 영향을 받나요?
이 논문의 라우터 공격에는 영향을 받지 않습니다. 중개자가 없기 때문입니다. 회사 게이트웨이나 모델 집계 서비스 등 어떤 이유로든 Claude Code를 프록시를 거쳐 쓰고 있다면, 그 프록시가 같은 위치에 있습니다.
OpenRouter, LiteLLM 같은 잘 알려진 집계 서비스는 어떤가요?
논문이 측정한 것은 세 마켓플레이스의 유료 라우터 28개와, 주로 두 오픈 소스 템플릿으로 만든 무료 라우터 400개입니다. LiteLLM과 OpenRouter는 배경으로 언급될 뿐 시험 대상이 아닙니다. 구조적인 요점은 모든 라우터에 적용됩니다. 라우터는 트래픽을 읽고 바꿔 쓸 수 있으며, 가시성은 무결성과 다른 속성입니다. 직접 호스팅하는 프록시에 대해서는 위의 10월 1일 업데이트에서 LiteLLM 권고 11건을 다룹니다.
자동 승인된 401개 세션은 누구의 것이었나요?
트래픽이 연구자들의 미끼 릴레이에 도달한 제3자들의 것입니다. 직접 만들지 않은 라우터를 거쳐 자동 승인 에이전트 세션을 실행하고 있다면 중단하고, 그 라우터를 지난 모든 자격 증명을 교체하며, 예상하지 못한 도구 호출이 있는지 세션 로그를 검토하십시오.
참고 문헌
-
Hanzhi Liu, Chaofan Shou, Hongbo Wen, Yanju Chen, Ryan Jingyang Fang, Yu Feng, “Your Agent Is Mine: Measuring Malicious Intermediary Attacks on the LLM Supply Chain,” arXiv:2604.08407v1, 2026년 4월 9일, ACM Conference on Computer and Communications Security(2026년 10월) 게재 예정. 전문은 2026년 10월 1일과 2일에 읽었습니다. 참고한 절: Introduction과 2.1(라우터의 정의, 네 홉 예시, TLS 종료), 2.2(제공업체 수준 무결성 메커니즘의 부재), 4.1과 4.2(네 가지 공격 클래스,
requests에서reqeusts로 바뀌는 예, 다섯 가지 트리거 계열), 5.1(4단계 파이프라인과 정의), 5.2와 Table 3, 4(주입한 유료 1개와 무료 8개, 트리거를 가진 무료 2개, AWS 카나리를 사용한 무료 17개, ETH를 빼간 1개), 5.3(유출된 키와 미끼: 1억 토큰, 7개가 넘는 Codex 세션, 147개 IP에서 온 4만 건 이상의 접근 시도, 약 20억 토큰, 약 13 GB, 자격 증명 99개, 세션 440개, 프로젝트 또는 호스트 398곳, YOLO mode 401개), 5.4(유료 접근에 관한 문장을 포함한 핵심 발견), 5.5(범위), 6과 Table 5(Mine, 네 프레임워크, 모듈당 요청 1,000건, 100%와 99.6% 호환성), 7과 Table 6(세 가지 방어책과 결과), 8.2와 8.3(서명된 응답 봉투, MCP), 9(MCP 서버와 라우터의 위치 차이), Appendix A(보관, 자격 증명 폐기, 50달러 미만의 인출, Mine 비공개). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
LiteLLM 저장소 권고 GHSA-3cv6-jpf6-8222(CVE-2026-84377, PYSEC-2026-4066), “Authenticated SSRF and provider-credential exfiltration via unvalidated request-body routing parameters,” 2026년 8월 26일 저장소에 게시, 9월 2일 NVD 등재, 9월 30일 GitHub 검토. 2026년 10월 1일 저장소 페이지와 OSV 기록으로 확인했습니다. Impact와 Workarounds 문장 전체는 권고에서 인용했습니다. OSV 기록의 Patches 줄은 “Fixed in 1.96.2, 1.95.1, 1.94.3, 1.93.2, 1.92.2, 1.91.5, 1.90.7, 1.89.7, and 1.88.6”이며, 저장소 페이지에는 “Affected versions <1.94.0”이라고 되어 있습니다. 11건이라는 수는 PyPA 권고 데이터베이스의 PYSEC-2026-4066부터 PYSEC-2026-4076까지의 항목으로, 모두
litellm패키지에 대한 것이며 날짜는 모두 2026년 10월 1일이고 철회된 것은 없습니다. ↩↩↩↩↩ -
Anthropic, Hooks reference, Claude Code 문서, 2026년 10월 2일 확인. PreToolUse는 “Before a tool call executes. Can block it”(도구 호출이 실행되기 전. 차단할 수 있음)에 실행되고, PostToolUse는 “After a tool call succeeds”(도구 호출이 성공한 뒤)에 실행됩니다. “Any other exit code doesn’t block on its own for most hook events”(대부분의 훅 이벤트에서 그 밖의 종료 코드는 그 자체로 차단하지 않는다)이며, 시간 초과된 명령 훅은 “doesn’t block the tool call”(도구 호출을 차단하지 않는다). 또한 “a mistyped path in settings.json leaves the gate silently disabled.”(settings.json의 경로를 잘못 입력하면 게이트가 아무 경고 없이 꺼진 채로 남는다)라고 적혀 있습니다. ↩↩↩
-
GitHub Security Advisory GHSA-hx8v-g79f-8w5f(CVE-2026-59823, PYSEC-2026-4070), “LiteLLM Proxy has server-side request forgery via the
user_configrequest parameter,” 2026년 9월 17일 게시, 2026년 10월 1일 OSV로 확인. 영향 범위<= 1.83.8, 패치1.83.9이며, 권고는 이 릴리스의 날짜를 2026년 4월 17일로 적고 있습니다. ↩ -
2026년 10월 1일에 확인한 OSV 기록: PYSEC-2026-4067(CVE-2026-12773, MCP 프록시 인증), PYSEC-2026-4069(CVE-2026-12798, MCP OpenAPI 사양 로더), 그리고 PYSEC-2026-4068, 4071, 4072, 4073, 4074, 4075, 4076. 이 9건의 바탕이 된 GitHub 권고는 NVD에 등재된 날과 같은 2026년 6월 21일에 게시되었으며, 모두 VulDB를 인용합니다. 업로드 날짜와 현재 버전은 같은 날 확인한 PyPI 프로젝트 페이지와 그 JSON에서 가져왔습니다. 1.88.6부터 1.95.1까지는 8월 9일, 1.96.2는 8월 11일, 1.97.0은 8월 16일, 1.103.2는 10월 1일입니다. ↩↩↩
-
PyPI에서 받은
litellm1.95.0 wheel(영향 범위는 1.95.0부터 1.95.1의 수정 전까지)을 필자가 직접 읽은 내용, 2026년 10월 1일.litellm/proxy/auth/auth_utils.py에서_check_banned_params는general_settings.get("allow_client_side_credentials") is True일 때 아무것도 거부하지 않고 반환합니다. 그 밖의 경우에는 금지 목록에 있는 매개변수를 본문에 담은 요청을 거부하지만, 배포의configurable_clientside_auth_params가 그 매개변수를 허용하면 예외입니다. 이 릴리스의 금지 목록에는vertex_ai_credentials와 관측 도구의 자격 증명 및 호스트가 포함됩니다. 제가 읽은 것은 영향받는 릴리스 하나이며, 아홉 개 라인 전부가 아닙니다. ↩