BSP Protection et leaks

Une map GMod est-elle sûre ? Vérifie le BSP avant de l’installer

Une map GMod peut-elle nuire à ton serveur ? Ce que lua_run peut faire, ce que GMod bloque, comment vérifier entités et pakfile d’un BSP avant de l’installer.

Oui, une map peut nuire à un serveur GMod, et les principaux risques peuvent être vérifiés à l’avance. La voie la plus importante est l’entité lua_run : elle exécute sur le serveur du code Lua stocké dans les données d’entités de la map. En dehors de cela, une map peut perturber un serveur sans le moindre code, par exemple avec un déluge d’entités. Tu repères les deux en listant les entités et le pakfile et en chargeant d’abord la map sur un serveur séparé.

Ce qu’un BSP peut contenir et ce qu’il ne peut pas contenir

Un BSP n’est pas un programme, mais un ensemble de blocs de données appelés lumps. Deux d’entre eux comptent pour la sécurité : le lump d’entités, une liste en texte de toutes les entités avec leurs propriétés, et le pakfile, une archive ZIP contenant des fichiers intégrés. La structure complète est expliquée dans Qu’est-ce qu’un fichier BSP ?. Cela laisse à une map deux moyens de faire plus qu’afficher de la géométrie : des entités qui exécutent quelque chose, et des fichiers que le jeu monte au chargement.

Garry’s Mod a durci le second moyen. Depuis les correctifs de sécurité de décembre 2023, le jeu contrôle les fichiers intégrés par rapport à une whitelist. Ce qui échoue n’est pas monté, et la console affiche :

BSP embedded file failed whitelist check - '<path of the file>'

Les notes de patch de Facepunch mentionnent nommément la whitelist et citent des entrées autorisées par la suite, comme materials/*.raw et scripts/vehicles/*.txt. Facepunch n’a pas documenté la liste complète. La bibliothèque de système de fichiers de la version actuelle du jeu contient une liste de motifs exactement dans ce format, qui couvre entre autres les models, les matériaux, les sons, les particules, le navmesh, les soundscapes et les fichiers texte sous maps/ et data_static/, mais aucun motif pour les fichiers Lua. Que cette liste soit la whitelist est notre lecture du fichier et n’est pas confirmé par Facepunch, et nous n’avons pas testé dans un jeu en cours d’exécution si un .lua du pakfile est chargé. Traite donc les fichiers Lua dans un pakfile comme une anomalie que l’auteur devrait expliquer.

lua_run : du code Lua directement depuis la map

garrysmod.fgd décrit lua_run brièvement par « Runs Lua Code ». L’entité possède un keyvalue Code, le spawnflag « Run code on spawn » et deux inputs : RunCode exécute le code stocké, RunPassedCode exécute du code qu’un autre output envoie en paramètre. Le code tourne sur le serveur et y a les mêmes possibilités qu’un addon installé.

C’est un outil légitime. gm_construct, livrée avec le jeu, contient elle-même deux entités lua_run, et l’une d’elles affiche une indication aux joueurs (abrégé) :

{
"targetname" "ColorRoomHint"
"Code" "if ( TRIGGER_PLAYER ) then TRIGGER_PLAYER:SendHint( 'ColorRoom', 0 ) else Msg( 'No Player!!?/n' ) end"
"classname" "lua_run"
}

Ce qui compte n’est donc pas de savoir si une map contient lua_run, mais ce que dit le code. En le lisant, guette ces signaux d’alerte :

  • Des accès réseau comme http.Fetch ou HTTP. Une map n’a aucun besoin de parler à un serveur tiers.
  • Du code chargé à l’exécution via RunString ou CompileString. Le vrai code se trouve alors ailleurs, et tu ne vérifies que la coquille.
  • Des chaînes illisibles, par exemple de longues suites de nombres.
  • Des commandes console et des rangs, c’est-à-dire RunConsoleCommand, game.ConsoleCommand ou des modifications des groupes d’utilisateurs.
  • RunPassedCode dans des outputs. Le code ne se trouve alors pas dans le lua_run, mais dans l’output d’une autre entité. Cherche donc dans toute la liste des entités.

Nous n’avons trouvé aucun réglage serveur qui interdise aux maps d’exécuter du Lua, ni sur le wiki GMod ni dans la liste des convars. Garry’s Mod bloque seulement certaines commandes console pour Lua, parmi lesquelles rcon_password et sv_cheats. Cela ne remplace pas la lecture du code.

Des ennuis sans une seule ligne de code

Entités de commande. Dans d’autres jeux Source, point_servercommand et point_clientcommand envoient des commandes à la console. Dans Garry’s Mod, les deux sont désactivées : le base.fgd du jeu les liste en commentaire avec une note indiquant qu’elles sont désactivées dans GMod, et Facepunch les a retirées de Hammer parce qu’elles ne fonctionnent pas dans Garry’s Mod. Le wiki Valve Developer Community cite les abus comme raison. Si tu les trouves dans une map, celle-ci vient probablement d’un autre jeu.

Déluges d’entités. Une map peut créer des entités à l’exécution, par exemple via point_template avec env_entity_maker ou via npc_maker, souvent pilotés par un logic_timer. Si cela tourne sans frein, tous les edicts finissent par être utilisés. D’après le wiki GMod, la limite se situe autour de 8176 entités mises en réseau ; le serveur signale d’abord Warning: free edicts below threshold et, dans le pire des cas, s’arrête avec ED_Alloc: no free edicts. La cause peut tout aussi bien être une erreur de construction qu’un acte délibéré. Le comptage des edicts est expliqué dans l’article sur la limite d’edicts et « no free edicts ».

Données piégées. Facepunch continue de durcir le jeu contre les maps qui provoquent des crashs. La mise à jour de novembre 2025 mentionne, entre autres, une protection contre des valeurs absurdes du fog controller, contre une boucle de rechargement via player_loadsaved, ainsi que des limites sur le nombre de props statiques. Garde donc le serveur à jour : une ancienne version est plus vulnérable à de telles maps.

Contenu. Des textures et des models manquants ou un téléchargement très volumineux ne sont pas une attaque, mais ils font fuir les joueurs.

D’où vient le fichier

Le risque dépend davantage de la source que du format de fichier. Le lump d’entités est du texte brut et peut être modifié avec des outils simples. Quiconque remet une map en ligne peut donc y ajouter un lua_run sans changer son nom ni son apparence. Avec des copies leakées, tu ne sais pas qui a touché le fichier en dernier.

Outre le BSP lui-même, le paquet peut être le problème : si la map arrive dans une archive avec un dossier lua ou un addon, ce code s’exécute sans aucun lua_run. Lis-le comme n’importe quel autre addon. Ce à quoi il faut faire attention à l’achat est décrit dans acheter des maps GMod en sécurité.

Le contrôle avant l’installation

  1. Établis la provenance. Récupère la map auprès de son auteur ou sur une plateforme qui montre qui l’a mise en ligne.
  2. Regarde le paquet. Attends-toi à un .bsp, éventuellement avec un navmesh. Lis en entier les fichiers Lua et les addons du paquet.
  3. Liste les entités. Le lump d’entités est du texte brut, une recherche de texte dans le BSP suffit donc. Cherche lua_run, RunPassedCode, point_servercommand et point_clientcommand. Le Map Scanner trouve les entités à risque comme point_servercommand ou lua_run et vérifie la présence d’un spawnpoint. C’est à toi d’évaluer le code.
  4. Liste le pakfile. bspzip -dir, depuis le dossier bin de Garry’s Mod, affiche chaque fichier intégré avec son chemin. Le Map Scanner liste aussi les fichiers Lua et les assets intégrés. Attends-toi à materials/, models/, sound/ et à des dossiers du même genre.
  5. Teste de façon isolée. Lance la map sur un serveur sans vraies données de joueurs et sans accès à ta base de données. Lis la console : les messages de whitelist, les erreurs Lua et les avertissements d’edicts y apparaissent.
  6. Conserve le fichier vérifié. Répète les étapes 3 à 5 à chaque mise à jour.
bspzip -dir rp_example_v2.bsp
bspzip -repack copy_rp_example_v2.bsp

Tu n’as besoin de la seconde ligne que pour les maps compressées. Leurs lumps sont compressés, si bien qu’une simple recherche de texte dans le fichier ne trouve rien, et bspzip -dir échoue lui aussi. D’après son texte d’aide, -repack sans -compress décompresse de nouveau le fichier. Dans notre test, cependant, le bspzip de la version actuelle de Garry’s Mod s’est arrêté sur une map compressée sans aucun message, alors que le bspzip de Team Fortress 2 a décompressé le même fichier. Travaille sur une copie quand tu fais cela.

Le Map Scanner vérifie en plus la cohérence du header, des magic bytes, de la table des lumps et des offsets, et accepte les fichiers BSP jusqu’à 50 Mo. Ce qu’un mappeur passe en revue avant de publier se trouve dans la checklist pour vérifier un BSP avant publication.

Questions fréquentes

sv_allowcslua 0 empêche-t-il les maps d’exécuter du Lua ?

Non. D’après le wiki GMod, sv_allowcslua détermine si les clients peuvent utiliser lua_openscript_cl et lua_run_cl, c’est-à-dire leurs propres scripts sur leur propre machine. Ce réglage n’a rien à voir avec l’entité lua_run, qui tourne sur le serveur.

Que faire si je trouve du code suspect dans une map ?

Ne l’installe pas et demande à l’auteur à quoi sert le code. Si tu n’obtiens pas de réponse plausible, signale le fichier à la plateforme d’où il vient et utilise une autre map.

Un scan suffit-il, ou dois-je quand même tester la map ?

Teste-la quand même. Un scan montre quelles entités et quels fichiers se trouvent dans le BSP. Ce qu’une chaîne logique fait à l’exécution, par exemple combien d’entités elle crée, ne devient visible que sur un serveur en fonctionnement.