@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 3f5d902d2a
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

Validate API tokens in constant time (#25781)

Signed-off-by: rentianyue-jk <rentianyue-jk@360shuke.com> Signed-off-by: Russell Bryant <rbryant@redhat.com> Co-authored-by: rentianyue-jk <rentianyue-jk@360shuke.com>

Russell Bryant committed Sep 27, 2025 at 06:09 UTC 3f5d902d2a6fa752925d49b8c219b9515b37c0a6
1 file changed +24 -4
vllm/entrypoints/openai/api_server.py
+24 -4
@@ -3,12 +3,14 @@
3
4 import asyncio
5 import gc
6 +import hashlib
7 import importlib
8 import inspect
9 import json
10 import multiprocessing
11 import multiprocessing.forkserver as forkserver
12 import os
13 +import secrets
14 import signal
15 import socket
16 import tempfile
@@ -1252,7 +1254,7 @@ def load_log_config(log_config_file: Optional[str]) -> Optional[dict]:
1254 class AuthenticationMiddleware:
1255 """
1256 Pure ASGI middleware that authenticates each request by checking
1255 - if the Authorization header exists and equals "Bearer {api_key}".
1257 + if the Authorization Bearer token exists and equals anyof "{api_key}".
1258
1259 Notes
1260 -----
@@ -1263,7 +1265,26 @@ class AuthenticationMiddleware:
1265
1266 def __init__(self, app: ASGIApp, tokens: list[str]) -> None:
1267 self.app = app
1266 - self.api_tokens = {f"Bearer {token}" for token in tokens}
1268 + self.api_tokens = [
1269 + hashlib.sha256(t.encode("utf-8")).digest() for t in tokens
1270 + ]
1271 +
1272 + def verify_token(self, headers: Headers) -> bool:
1273 + authorization_header_value = headers.get("Authorization")
1274 + if not authorization_header_value:
1275 + return False
1276 +
1277 + scheme, _, param = authorization_header_value.partition(" ")
1278 + if scheme.lower() != "bearer":
1279 + return False
1280 +
1281 + param_hash = hashlib.sha256(param.encode("utf-8")).digest()
1282 +
1283 + token_match = False
1284 + for token_hash in self.api_tokens:
1285 + token_match |= secrets.compare_digest(param_hash, token_hash)
1286 +
1287 + return token_match
1288
1289 def __call__(self, scope: Scope, receive: Receive,
1290 send: Send) -> Awaitable[None]:
@@ -1276,8 +1297,7 @@ class AuthenticationMiddleware:
1297 url_path = URL(scope=scope).path.removeprefix(root_path)
1298 headers = Headers(scope=scope)
1299 # Type narrow to satisfy mypy.
1279 - if url_path.startswith("/v1") and headers.get(
1280 - "Authorization") not in self.api_tokens:
1300 + if url_path.startswith("/v1") and not self.verify_token(headers):
1301 response = JSONResponse(content={"error": "Unauthorized"},
1302 status_code=401)
1303 return response(scope, receive, send)