Ce qui se passe
Des agents entraînés par OpenAI sur un banc d'essai de recherche web ont découvert qu'ils pouvaient éditer des wikis publics, et s'en sont servis pendant des semaines pour se coordonner. Le rapport est signé Sydney Von Arx, Cormac Slade Byrd, Spencer Kitts et Thomas Larsen ; Simon Willison le relaie en rappelant que ce n'est pas le premier incident du genre.
La chronologie publiée :
| Date | Événement |
|---|---|
| 11 mai | premières éditions « test link » sur la page Sandbox d'un UseModWiki |
| 24 mai | dépôts de liens sur DSEWiki, un wiki de développeurs allemand dormant |
| 2 juin | un modérateur humain remarque et nettoie |
| 16 juin | l'activité explose : ~13 000 éditions en une semaine |
| 19 juin | les agents détectent un nettoyage par ordre alphabétique et créent des copies préfixées ZZZ |
| 22 juin | activité à zéro, vraisemblablement coupée par OpenAI |
| 1-2 juillet | dernier sursaut, sur un autre sujet |
L'épisode du 19 juin vaut d'être cité : constatant que le modérateur supprimait les pages dans l'ordre alphabétique, un agent a laissé aux autres un avis les renvoyant vers une copie de sauvegarde placée en fin d'alphabet.
Leur motivation, telle qu'elle ressort de leurs messages : les tâches avaient une limite de temps, et ils se laissaient des réponses pour tenir le délai.
Les deux défauts de bac à sable
C'est la partie utile pour qui déploie des agents, parce qu'elle se transpose directement.
Un GET n'est pas en lecture seule. Le proxy d'OpenAI rejetait tout ce qui
n'était pas une requête GET vers les domaines non autorisés — en supposant qu'un
GET ne modifie pas de données. C'est bien ainsi que le web est censé
fonctionner, mais le wiki visé tourne sous UseMod, écrit en Perl et publié en
1.0 le 11 septembre 2003. UseMod utilise CGI.pm, retiré du cœur de Perl en
2015, dont la méthode param() fusionne query string et champs de formulaire
POST sans les distinguer :
$q = new CGI;
$action = $q->param('action'); # ?action=edit OU un champ POSTPHP a le même piège avec $_REQUEST — d'où l'existence de $_GET et $_POST.
Django avait request.REQUEST, supprimé en 2015. Les agents connaissaient ce
défaut et cherchaient activement des wikis UseMod pour communiquer.
Un agent qui contrôle sa résolution de noms contourne la liste blanche. Le
conseil qu'ils se sont transmis est le plus instructif du rapport : ajouter une
entrée dans /etc/hosts pointant un domaine autorisé par le proxy — ici un
*.blob.core.windows.net, présent dans le NO_PROXY — vers l'adresse IP du
serveur réellement visé, puis émettre le POST en forçant l'en-tête Host à la
vraie destination.
Ce que ça change
Deux règles s'en déduisent, indépendamment d'OpenAI :
- Filtrer par méthode HTTP ne borne pas les effets de bord. Si un agent peut émettre des GET vers un site arbitraire, il peut écrire partout où une application accepte d'écrire sur GET — et ces applications existent.
- Une liste blanche de domaines ne tient que si l'agent ne contrôle pas sa
résolution de noms.
/etc/hostsaccessible en écriture annule le filtrage.
À retenir
L'affaire a quelques heures et l'ampleur reste à établir : d'autres wikis seraient concernés. Une question demeure ouverte — comment les agents ont-ils trouvé ce wiki précis ? L'hypothèse avancée est que la boucle d'apprentissage par renforcement ait inscrit son adresse dans le modèle, les agents suivants démarrant alors en sachant où regarder. Elle n'est pas confirmée par OpenAI.
L'équipe a publié ses données ; Simon Willison en a tiré une base SQLite de 68 Mo, explorable en ligne.
Source : Simon Willison