système : OPÉRATIONNEL
← retour à tous les hacks
SUPPLY CHAIN MEDIUM NEW

trust_remote_code=False n'est pas une frontière : la RCE récurrente au chargement de modèle dans vLLM

CVE-2026-27893 (divulguée le 27 mars 2026) est le troisième contournement de trust_remote_code dans vLLM. Deux fichiers de modèle codent en dur trust_remote_code=True, annulant silencieusement le choix de l'opérateur et ouvrant une RCE depuis un dépôt de modèle malveillant.

2026-06-05 // 6 min affects: vllm, vllm-0.10.1-to-0.17.x, nemotron-vl, kimi-k25

En bref Dans vLLM, --trust-remote-code=False est censé empêcher un dépôt de modèle d’exécuter du Python arbitraire sur votre hôte d’inférence. CVE-2026-27893, divulguée le 27 mars 2026 (CVSS 8.8), est la troisième fois que cette frontière est contournée — cette fois parce que deux fichiers de modèle codent en dur trust_remote_code=True. Sont concernées les versions 0.10.1 à 0.17.x ; le correctif est arrivé en 0.18.0. La leçon n’est pas un bug isolé mais un schéma : un opt-in fichier par fichier n’est pas une frontière de confiance.

De quoi s’agit-il ?

CVE-2026-27893 est une défaillance de mécanisme de protection (CWE-693) dans vLLM, le moteur d’inférence et de service qui sous-tend une grande partie des déploiements LLM en production. Les opérateurs peuvent passer --trust-remote-code=False pour refuser l’exécution du Python embarqué dans un dépôt de modèle. L’avis de sécurité GitHub, publié le 27 mars 2026, montre que deux fichiers d’implémentation de modèle ignorent ce paramètre et passent un littéral trust_remote_code=True à Hugging Face Transformers — le code distant s’exécute donc malgré tout.

Ce qui mérite couverture, ce n’est pas la CVE isolée mais sa filiation. L’avis nomme lui-même deux prédécesseurs : CVE-2025-66448 (1er décembre 2025, le chemin de chargement de config via auto_map) et CVE-2026-22807 (le chemin auto_map plus large au démarrage). Chacune a été corrigée ; à chaque fois la même frontière de confiance est retombée par un autre chemin de code. CVE-2026-27893 est la troisième de cette série.

Comment ça marche

Le choix de l’opérateur est bien propagé dans la hiérarchie de configuration de vLLM sous la forme self.config.model_config.trust_remote_code. Les deux points d’appel vulnérables ne le lisent simplement pas. Selon l’avis, les lignes fautives sont :

# vllm/model_executor/models/nemotron_vl.py (chargement de l'encodeur de vision)
AutoModel.from_config(config, trust_remote_code=True)

# vllm/model_executor/models/kimi_k25.py (chargement du processeur d'image)
cached_get_image_processor(model_name, trust_remote_code=True)

Parce que le littéral True écrase le paramètre global, Hugging Face Transformers télécharge et exécute du Python depuis le dépôt référencé au moment du chargement, avec les privilèges du processus vLLM. Le scénario de déclenchement : un attaquant publie un dépôt de modèle ciblant l’architecture Nemotron-VL ou Kimi-K25 ; un opérateur le charge — convaincu que --trust-remote-code=False le protège ; vLLM aiguille vers l’un de ces deux fichiers ; le True codé en dur l’emporte ; le code du dépôt s’exécute. Le contournement est silencieux — aucun avertissement, aucune entrée de journal ne signale que le paramètre de l’opérateur a été ignoré. Le CVSS l’évalue à 8.8 (AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H) : accessible par le réseau, sans privilège attaquant, mais l’opérateur doit initier le chargement (UI:R).

Pourquoi c’est important

La récurrence est le cœur du sujet. vLLM délègue le comportement propre à chaque modèle à des fichiers individuels dans model_executor/models/, et chaque fichier doit honorer indépendamment le drapeau global trust_remote_code. Il n’existe aucun point de passage central qui empêche un fichier de coder True en dur. Résultat : chaque nouvelle implémentation de modèle est une occasion de réintroduire la même classe — ce qui s’est précisément produit trois fois, à travers config.py, le chemin auto_map au démarrage, et désormais deux fichiers de modèle.

Pour les défenseurs, le danger pratique est un faux sentiment de sécurité. Les équipes qui ont adopté --trust-remote-code=False comme contrôle peuvent faire passer des modèles par un chemin affecté sans aucune indication que le contrôle est inopérant. Et la leçon dépasse vLLM : tout cadre qui disperse l’application d’un réglage critique pour la sécurité sur de multiples fichiers indépendants, sans médiation centralisée, est structurellement exposé à cette défaillance. À la divulgation, il n’existait pas de preuve de concept publique ni de preuve d’exploitation dans la nature, mais les versions touchées couvrent une année de releases (0.10.1 à 0.17.x).

Défenses

  1. Passez à vLLM 0.18.0 ou ultérieur. Le correctif de la PR #36192 remplace le True codé en dur par self.config.model_config.trust_remote_code aux deux points d’appel. Vérifiez votre version avec pip show vllm.
  2. Ne faites pas de trust_remote_code=False votre seule frontière. Exécutez l’inférence dans un conteneur minimal à sortie réseau restreinte, isolez le niveau de service des magasins de données sensibles et segmentez-le pour limiter les déplacements latéraux en cas de compromission.
  3. Vérifiez la provenance des modèles. Restreignez le chargement à des éditeurs de confiance et signés ; calculez une empreinte ou signez les artefacts de modèle avant chargement plutôt que de vous reposer sur un drapeau d’exécution — en particulier pour les architectures Nemotron-VL et Kimi-K25.
  4. Scannez vos propres builds. Comme cette classe a récidivé, recherchez dans model_executor/models/*.py les littéraux trust_remote_code=True (et les appels from_pretrained / from_config qui ne propagent pas la config) dans tout vLLM personnalisé ou forké. Intégrez ce contrôle à votre CI pour qu’un futur fichier de modèle ne puisse pas le réintroduire.
  5. Surveillez le contournement silencieux. Lorsque les modèles sont préchargés, un téléchargement sortant de .py depuis huggingface.co durant le chargement — ou un processus enfant inattendu sous un worker vLLM — est un bon signal de chasse indiquant qu’un code distant s’est exécuté à tort.

Statut

ÉlémentRéférenceDateNotes
Avis CVE-2026-27893GitHub (GHSA-7972-pg2x-xr59)2026-03-27trust_remote_code=True codé en dur, CVSS 8.8, CWE-693
Versions affectéesvLLM0.10.1 → 0.17.xChemins de chargement Nemotron-VL et Kimi-K25
Version corrigéevLLM 0.18.0PR de correctif #36192
CVE-2025-66448GitHub (GHSA-8fr4-5q9j-m8gm)2025-12-01Premier contournement, auto_map dans le chemin de config
CVE-2026-22807Avis GitHub2026Deuxième contournement, chemin auto_map plus large au démarrage

Le bon cadrage n’est pas « corriger une CVE ». C’est que trust_remote_code dans vLLM s’est révélé une frontière poreuse trois fois de suite, et qu’une pile de service qui s’y fie comme contrôle ferme devrait ajouter de l’isolation et des vérifications de provenance qui ne dépendent pas d’un unique drapeau, fichier par fichier, correctement positionné.

Sources