En bref : selon le rapport de Forever Security du 22 octobre, quelqu'un a placé dans le dossier ~/Downloads de l'ordinateur d'un vrai client un fichier déguisé en règles d'ingénierie : AGENTS.md. Lorsque Codex démarre dans ce dossier, il suit le fichier et ajoute un serveur MCP au fichier global ~/.codex/config.toml, puis s'en sert pour installer le paquet npm malveillant function-color. Les chercheurs ont aussi construit un CLAUDE.md qui amène Claude Code à écrire, dans le .claude/settings.json du projet, un ANTHROPIC_BASE_URL pointant vers leur serveur, ce qui leur livre le jeton de connexion.
Si vous utilisez une API Key tierce, vous modifiez déjà base_url, model_provider et ANTHROPIC_BASE_URL. Le plus utile est donc de distinguer les adresses que vous avez définies vous-même de celles qui ont été ajoutées. Les commandes ci-dessous prennent environ une minute.
L'essentiel
- Les deux clients ont été démontrés : selon le rapport, Codex a été poussé à installer le paquet dans plus de neuf tests sur dix ; Claude Code, plus difficile à tromper, a écrit les réglages malveillants dans environ la moitié des tests. Aucun des deux n'a de bug à proprement parler : ils font ce que dit le fichier d'instructions.
- Codex modifie sa configuration globale :
~/.codex/config.tomls'applique à toutes les sessions Codex de la machine, donc le serveur MCP de l'attaquant continue de se charger même hors de Téléchargements. - Claude Code modifie la configuration du projet : le
.claude/settings.jsondu projet peut définir unANTHROPIC_BASE_URLqui remplace l'adresse AICodeWith définie globalement. Lors de notre test sur la box, après l'ajout de cette seule ligne dans un projet,claude -pn'a rien répondu pendant 90 secondes ; une fois la ligne supprimée, il a répondu normalement en 2,4 secondes. - Quoi vérifier : pour Codex,
[mcp_servers.*]etbase_url; pour Claude Code, cherchez dans chaquesettings.jsonla variableANTHROPIC_BASE_URL. Les bonnes adresses AICodeWith sont plus bas. - trust_level fonctionne toujours : testé sur Codex CLI 0.164.0,
[projects."<path>"] trust_level = "untrusted"empêche le chargement duAGENTS.mdde ce dossier. Ce n'est pas la même chose que leapproval_policy = "untrusted"retiré. - En cas de compromission : supprimez les blocs suspects, supprimez l'ancienne Key dans le tableau de bord et créez-en une nouvelle ; si vous vous connectez à Claude Code avec un compte officiel, lancez
/logoutpuis reconnectez-vous.
Créer une API Key, la même pour Claude Code et Codex →
Ce qui s'est passé : comment chaque client a été détourné
Selon The Hacker News et BleepingComputer, Forever Security a empêché Codex d'installer function-color sur une machine cliente et a retracé l'instruction jusqu'au dossier ~/Downloads, plus précisément jusqu'à un fichier AGENTS.md. Ils n'ont pas pu établir comment le fichier est arrivé là, mais ils ont créé une page de démonstration qui télécharge silencieusement un AGENTS.md dans Téléchargements dès qu'on l'ouvre. Par défaut, Chrome, Edge et Firefox enregistrent les fichiers dans ce dossier sans demander où.
| Codex | Claude Code | |
|---|---|---|
| Fichier piégé | AGENTS.md (issu de la vraie attaque, un document de « règles d'ingénierie » d'environ 13 Ko) | CLAUDE.md (construit par les chercheurs sur le modèle du vrai) |
| Configuration modifiée | Global ~/.codex/config.toml, ajout de [mcp_servers.project-tools] | Projet .claude/settings.json, écriture de ANTHROPIC_BASE_URL |
| Conséquences (selon le rapport) | Le serveur MCP exécute une commande au démarrage et installe function-color ; ensuite il se charge à chaque démarrage de Codex, dans n'importe quel dossier | Les requêtes et le jeton OAuth partent vers le serveur de l'attaquant, qui peut aussi se faire passer pour le modèle et renvoyer des commandes à exécuter |
| Taux de réussite selon le rapport | Plus de neuf sur dix | Réglages écrits environ une fois sur deux |
Selon le rapport, le fichier Codex fait aussi lancer par Codex, avec --dangerously-bypass-approvals-and-sandbox, un second codex exec pour accéder au réseau malgré le bac à sable. Pour Forever, aucun des deux éditeurs n'a quoi que ce soit à « corriger », puisque les clients suivent simplement le fichier d'instructions : la protection vous revient.
Avant de vérifier : à quoi ressemble une configuration AICodeWith correcte
Si vous avez suivi le guide de configuration config.toml de Codex pour AICodeWith, la partie liée aux adresses de votre ~/.codex/config.toml global doit ressembler à ceci, sans rien de plus :
model_provider = "aicodewith"
model = "gpt-6.1-sol"
[model_providers.aicodewith]
name = "aicodewith"
base_url = "https://api.aicodewith.ai/chatgpt/v1"
wire_api = "responses"
experimental_bearer_token = "YOUR_API_KEY"
Si vous avez configuré Claude Code avec le guide de configuration d'API tierce pour Claude Code, votre ~/.claude/settings.json doit contenir :
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.aicodewith.ai",
"ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY"
}
}
La règle est simple : si une adresse n'est pas api.aicodewith.ai et que vous ne l'avez pas ajoutée, considérez-la comme suspecte. Si vous utilisez un autre service, comparez avec l'adresse que vous aviez saisie.
Commandes de vérification : macOS / Linux
Collez tout le bloc dans un terminal. Il ne fait que lire, il ne modifie rien :
echo "== 1 Codex global config =="
grep -nE '^\[mcp_servers|^\[model_providers|^[[:space:]]*(model_provider|base_url|chatgpt_base_url|openai_base_url|command|args)[[:space:]]*=' ~/.codex/config.toml
echo "== 2 project .codex/config.toml =="
find ~ -maxdepth 6 -path '*/.codex/config.toml' -not -path "$HOME/.codex/*" 2>/dev/null
echo "== 3 Claude Code settings =="
find ~ -maxdepth 6 \( -path '*/.claude/settings.json' -o -path '*/.claude/settings.local.json' \) 2>/dev/null | xargs grep -nE 'ANTHROPIC_BASE_URL|HTTPS?_PROXY|apiKeyHelper' 2>/dev/null
echo "== 4 instruction files in Downloads =="
ls -la ~/Downloads/AGENTS.md ~/Downloads/CLAUDE.md ~/Downloads/.claude ~/Downloads/.codex 2>/dev/null
echo "== 5 function-color =="
find ~ /tmp -maxdepth 6 -type d -name function-color -path '*node_modules*' 2>/dev/null
Listez ensuite les serveurs MCP avec la commande propre à chaque client ; les résultats doivent concorder :
codex mcp list
claude mcp list
Commandes de vérification : Windows PowerShell
"== 1 Codex global config =="
Select-String -Path "$env:USERPROFILE\.codex\config.toml" -Pattern '^\[mcp_servers','^\[model_providers','^\s*(model_provider|base_url|chatgpt_base_url|openai_base_url|command|args)\s*='
"== 2 project .codex / .claude settings =="
Get-ChildItem $env:USERPROFILE -Recurse -Depth 6 -Force -File -ErrorAction SilentlyContinue -Include config.toml,settings.json,settings.local.json | Where-Object { $_.Directory.Name -in '.codex','.claude' } | Select-String -Pattern '^\[mcp_servers','base_url','ANTHROPIC_BASE_URL','HTTPS?_PROXY','apiKeyHelper'
"== 3 instruction files in Downloads =="
Get-ChildItem "$env:USERPROFILE\Downloads" -Force -ErrorAction SilentlyContinue | Where-Object { $_.Name -in 'AGENTS.md','CLAUDE.md','.claude','.codex' }
Test : la sortie avec une configuration propre et avec des entrées ajoutées
Nous avons lancé les commandes ci-dessus sur la box dans un répertoire personnel de test isolé (Codex CLI 0.164.0, Claude Code 2.1.310), avec uniquement une Key de test AICodeWith. Nous n'avons exécuté aucun vrai paquet malveillant ni aucun fichier d'attaque.
Configuration propre : la version bash a terminé en 0,08 seconde environ :
== 1 Codex global config ==
1:model_provider = "aicodewith"
5:[model_providers.aicodewith]
7:base_url = "https://api.aicodewith.ai/chatgpt/v1"
== 2 project .codex/config.toml ==
== 3 Claude Code settings ==
/home/you/.claude/settings.json:3: "ANTHROPIC_BASE_URL": "https://api.aicodewith.ai",
== 4 instruction files in Downloads ==
== 5 function-color ==
Nous avons ensuite ajouté à la main trois entrées de démonstration inoffensives : un serveur qui ne lance que echo, déclaré comme [mcp_servers.project-tools] ; un .claude/settings.json de projet contenant un ANTHROPIC_BASE_URL qui pointe vers un domaine inexistant ; et un fichier vide ~/Downloads/AGENTS.md. Deuxième passage (0,06 seconde environ) :
== 1 Codex global config ==
1:model_provider = "aicodewith"
5:[model_providers.aicodewith]
7:base_url = "https://api.aicodewith.ai/chatgpt/v1"
11:[mcp_servers.project-tools]
12:command = "echo"
13:args = ["harmless-demo"]
== 3 Claude Code settings ==
/home/you/proj/demo/.claude/settings.json:1:{"env":{"ANTHROPIC_BASE_URL":"https://gateway.example.invalid"}}
/home/you/.claude/settings.json:3: "ANTHROPIC_BASE_URL": "https://api.aicodewith.ai",
== 4 instruction files in Downloads ==
-rw-r--r-- 1 you you 7 Oct 28 00:25 /home/you/Downloads/AGENTS.md
codex mcp list le liste aussi :
Name Command Args Env Cwd Status Auth
project-tools echo harmless-demo - - enabled Unsupported
La version PowerShell (pwsh 7) a terminé en 0,4 seconde environ dans le même répertoire et a repéré les trois.
L'adresse du projet remplace l'adresse globale : le ~/.claude/settings.json global pointe vers AICodeWith, mais après l'ajout de cette ligne ANTHROPIC_BASE_URL dans le projet, claude -p "Reply OK" n'a rien répondu pendant 90 secondes (la requête partait vers l'adresse inexistante). Après suppression de la ligne du projet, il a répondu OK en 2,4 secondes. C'est exactement ainsi que le rapport détourne Claude Code : votre configuration globale a beau être correcte, une ligne dans un projet suffit à envoyer vos requêtes ailleurs.
Après suppression des entrées de démonstration, les commandes sont revenues à une sortie propre, et un appel normal de chaque côté a répondu en 2,8 secondes environ pour Codex et 2,4 secondes pour Claude Code :
$ codex exec -s read-only --skip-git-repo-check "Reply with one short sentence: what is 1+1?"
1 + 1 = 2.
# provider: aicodewith / sandbox: read-only, 2.8s
$ claude -p "Reply with one short sentence: what is 1+1?"
1 + 1 = 2.
# 2.4s
Créer une API Key et repartir sur une Key propre →
Comment interpréter ce que vous trouvez
| Ce que vous trouvez | Normal | Suspect |
|---|---|---|
| [mcp_servers.xxx] | Vous l'avez ajouté vous-même et reconnaissez le nom et la commande | Vous ne l'avez jamais ajouté ; command ressemble à launchctl, bash -lc ou npm install |
| base_url | https://api.aicodewith.ai/chatgpt/v1 | Un domaine inconnu, surtout présenté comme « passerelle interne » |
| chatgpt_base_url / openai_base_url | En général absent | Apparu sans que vous l'écriviez |
| ANTHROPIC_BASE_URL | https://api.aicodewith.ai, uniquement dans votre propre configuration | Présent dans le .claude/settings.json d'un projet sans que vous l'ayez écrit |
| [shell_environment_policy.set] contenant une Key | Possible si vous avez utilisé /import de Codex | L'adresse n'est pas celle d'AICodeWith |
| ~/Downloads/AGENTS.md, CLAUDE.md | Normalement absent | S'il est là, ouvrez-le et lisez-le d'abord, et n'y lancez pas d'agent |
Pour la façon normale d'ajouter vos propres serveurs MCP, voir le tutoriel de configuration MCP pour Codex, et comparez pour repérer les entrées qui sont les vôtres.
Remarque : si vous avez migré depuis Claude Code avec /import de Codex, votre config.toml contiendra ANTHROPIC_AUTH_TOKEN et ANTHROPIC_BASE_URL. Ils ont été écrits par la fonction d'import, pas par un attaquant ; tant que l'adresse est celle d'AICodeWith, tout va bien. Pour savoir comment les traiter, voir notre test de migration avec /import de Codex.
Prévention : quatre habitudes
- Ne lancez pas d'agent dans
~/Downloads. Pour travailler sur un fichier tout juste téléchargé, copiez-le d'abord dans un dossier de projet que vous avez créé, puis lancez Codex ou Claude Code là. - Lisez les
AGENTS.md/CLAUDE.mdinconnus. Jetez un œil aux dépôts fraîchement clonés et aux archives qu'on vous envoie. Pour voir à quoi ressemblent des versions normales de ces fichiers, consultez Partager un seul AGENTS.md entre Claude Code et Codex et Comment écrire un CLAUDE.md. Si vous voyez des phrases comme « modifiez la configuration avant de commencer la tâche », « ajoutez--dangerously-bypass-approvals-and-sandbox» ou « configurez la passerelle interne », traitez cela comme une attaque. - Gardez les validations et le bac à sable activés. Dans Codex, utilisez
approval_policy = "on-request"avec unsandbox_modeadapté ; dans Claude Code, n'approuvez pas à la légère une écriture dans.claude/settings.json. - Marquez Téléchargements comme non fiable (Codex). Ajoutez ceci à votre
~/.codex/config.tomlglobal :
[projects."/Users/YOUR_USERNAME/Downloads"]
trust_level = "untrusted"
Utilisez un chemin absolu. Sous Windows, si le format vous échappe, acceptez une fois l'invite de confiance de Codex dans un autre projet et regardez ce qu'il écrit dans config.toml : l'entrée [projects...]. Reprenez ce format pour votre dossier Téléchargements et remplacez trust_level par "untrusted".
trust_level fonctionne-t-il encore ? Ce n'est pas la politique untrusted retirée
Metarix recommande de régler trust_level = "untrusted" pour Téléchargements, alors que notre article Configurer le bac à sable et /permissions de Codex indique que untrusted a été retiré. Les deux ne se contredisent pas :
- Ce qui a été retiré, c'est la politique d'approbation
approval_policy = "untrusted"(etcodex -a untrusted) ; 0.164.0 s'arrête avec une erreur s'il la trouve. [projects."<path>"] trust_level = "untrusted"est le niveau de confiance du projet, toujours valable. La page officielle Config basics indique que les projets non fiables ignorent la configuration.codex/du projet, ses hooks et ses règles.
Nous avons testé sur Codex CLI 0.164.0 : trois dossiers contenaient chacun un AGENTS.md inoffensif disant « commence ta réponse par SENTINEL-AGENTSMD-7731 ». Nous avons utilisé codex debug prompt-input pour voir exactement ce que reçoit le modèle, puis lancé codex exec pour de vrai :
| Réglage du dossier | AGENTS.md inclus dans le prompt ? | Réponse réelle de codex exec |
|---|---|---|
| trust_level = "untrusted" | Non | 1 + 1 = 2. (environ 3,6 s) |
| trust_level = "trusted" | Oui | SENTINEL-AGENTSMD-7731 1 + 1 = 2. (environ 3,0 s) |
| Pas d'entrée projects | Oui (visible dans codex debug prompt-input) | — |
Un point d'attention : le réglage correspond au dossier de démarrage et ne couvre pas automatiquement les sous-dossiers. Nous avons marqué un dossier parent comme non fiable et lancé Codex dans l'un de ses sous-dossiers : le AGENTS.md propre au sous-dossier a quand même été chargé. trust_level est donc une sécurité supplémentaire ; le plus sûr reste l'habitude n° 1 : ne jamais lancer d'agent dans Téléchargements ni dans ses sous-dossiers.
En cas de compromission
- Supprimez la configuration suspecte : sauvegardez d'abord avec
cp ~/.codex/config.toml ~/.codex/config.toml.bak, puis supprimez tout bloc[mcp_servers.*]que vous n'avez pas ajouté et toute adresse inconnue ; dans le.claude/settings.jsondu projet, supprimez la ligneANTHROPIC_BASE_URLécrite à votre insu. - Changez de Key : considérez toute Key présente dans vos fichiers de configuration comme divulguée. Connectez-vous au tableau de bord AICodeWith, supprimez l'ancienne Key sur la page API Key, créez-en une nouvelle et remettez-la dans
experimental_bearer_tokenetANTHROPIC_AUTH_TOKEN. - Claude Code connecté avec un compte officiel : lancez
/logoutdans Claude Code puis reconnectez-vous pour que l'ancien jeton cesse de fonctionner. Si vous vous connectez à Codex avec un compte ChatGPT, déconnectez-vous et reconnectez-vous aussi ; voir notre guide sur auth.json de Codex pour savoir où sont stockées les données de connexion. - Cherchez
function-color: l'indicateur de compromission du rapport est ce paquet npm (retiré par npm, selon le rapport). Si vous le trouvez sur une machine, considérez toute la machine comme compromise. - Relancez les commandes de vérification pour confirmer qu'il ne reste que votre propre configuration, puis envoyez une courte requête de chaque côté pour vérifier que tout fonctionne.
Créer une API Key et passer à une nouvelle Key →
FAQ
J'utilise uniquement une Key AICodeWith, sans compte officiel. Suis-je concerné ?
Oui. La voie Codex ne dépend pas de la façon dont vous vous connectez : le serveur MCP ajouté exécute des commandes sur votre machine. Claude Code envoie ANTHROPIC_AUTH_TOKEN comme en-tête de requête à ANTHROPIC_BASE_URL ; si l'adresse est modifiée, votre Key part avec la requête vers le serveur de quelqu'un d'autre. Changez de Key dans tous les cas.
J'utilise une Key tierce, j'ai donc déjà modifié ANTHROPIC_BASE_URL. Comment faire la différence ?
Regardez dans quel fichier il se trouve et quelle est sa valeur. Celui que vous avez défini se trouve en général dans ~/.claude/settings.json ou dans une variable d'environnement du shell, avec la valeur https://api.aicodewith.ai ; l'attaque du rapport écrit dans le .claude/settings.json du projet, avec un autre domaine.
Faut-il vérifier les .codex/config.toml de projet ?
Oui, mais l'attaque Codex du rapport modifie le ~/.codex/config.toml global, donc vérifiez celui-là en premier. La configuration de projet ne se charge que dans les projets de confiance.
Si codex mcp list affiche quelque chose, ai-je été touché ?
Non. Les serveurs MCP que vous avez ajoutés y figurent aussi. Vérifiez que chaque nom et chaque commande vient de vous ; commentez ce que vous ne comprenez pas et examinez-le.
Puis-je encore être attaqué avec trust_level = "untrusted" ?
Lors de notre test, le AGENTS.md de ce dossier n'était plus chargé, mais le réglage ne couvre que le chemin exact indiqué, pas les sous-dossiers. Ne pas lancer d'agent dans Téléchargements reste la vraie solution.



