Explorer
KNOW-ISS-001

GMod DHTML Panel : Accès filesystem hôte via File Picker depuis navigateur in-game

Domaine
cybersecu
Type
issue
Priorité
P0

Parent : [[INDEX-CYBERSECU]]

GMod DHTML Panel : Fuite filesystem et cookies via profil Chromium partagé

Problème

Le panel DHTML de Garry's Mod 13 embarque un moteur Chromium 86 obsolète (nov. 2020) exécuté dans le processus client. Ce navigateur in-game :

  1. Partage le cookie store et le localStorage de la machine hôte (même profil utilisateur Windows).
  2. Expose les APIs FileSystem (showOpenFilePicker, webkitRequestFileSystem) au JavaScript de pages tierces.
  3. Permet la lecture de fichiers locaux : le file picker s'ouvre directement sur le disque C:\ sans sandbox.
  4. Conserve l'historique et le localStorage entre les sessions de jeu (persistance après redémarrage complet).

Impact : n'importe quel joueur peut, depuis un PC factice in-game, charger une page web malveillante qui :

  • Lit des fichiers sensibles du serveur/client (chromium.log, crash dumps, config).
  • Exfiltre des cookies de tracking et potentiellement des sessions Google si le joueur se connecte.
  • Dépose des données persistantes (localStorage) accessibles aux joueurs suivants.

Solution

Correct (hardening requis)

  1. Isoler le profil Chromium : lancer le DHTML panel avec un --user-data-dir temporaire et unique par session de jeu, supprimé à la déconnexion.
  2. Désactiver les APIs de filesystem : supprimer showOpenFilePicker, showSaveFilePicker, webkitRequestFileSystem du contexte JS via CefV8Handler ou flags Chromium (--disable-file-system).
  3. Bloquer les requêtes réseau vers localhost : filtrer fetch/XMLHttpRequest/WebSocket vers 127.0.0.0/8 et ::1 via CefRequestHandler.
  4. Nettoyer les cookies au spawn : panel:ClearCookies() ou recréer le contexte à chaque utilisation du PC.
  5. Mettre à jour le moteur : remplacer Awesomium/Chromium 86 par une version récente avec sandbox GPU/process.
-- Exemple GMod : isolation du DHTML panel (correct)
local panel = vgui.Create("DHTML")
panel:SetAllowLua(false) -- Bloque l'exécution Lua depuis le JS
panel:OpenURL("about:blank")
-- Le cookie store est isolé si le panel est recréé à chaque session

Incorrect (état actuel)

-- Le panel partage le profil système et expose tout le JS
local panel = vgui.Create("DHTML")
panel:OpenURL("https://www.google.com") -- Cookies hôte visibles
-- showOpenFilePicker() accessible depuis n'importe quelle page tierce

Exemple

Preuve de lecture fichier local

// Exécuté depuis w3schools dans le navigateur in-game
const [fh] = await window.showOpenFilePicker();
const file = await fh.getFile();
const text = await file.text();
// Résultat : lecture complète de C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\chromium.log
// Le log contient des URLs internes (ex: https://leauding.cosmos-community.fr/loading/scprp?steamid=7656119...)

Preuve de persistance cross-session

// Session 1
localStorage.setItem("test", "hello");
// Quitter GMod complètement, redémarrer, reconnecter
// Session 2
localStorage.getItem("test"); // => "hello" (persistance confirmée)

Pourquoi ça marche

GMod 13 utilise le composant Awesomium (puis Chromium Embedded Framework sur certaines branches) intégré au client Source Engine. Par défaut, ce moteur hérite du profil utilisateur Windows (%LOCALAPPDATA%\Google\Chrome\User Data ou équivalent Source). Comme il n'est pas lancé en mode incognito avec un --user-data-dir isolé, il :

  • Réutilise les cookies existants.
  • Persiste le localStorage dans le dossier de profil partagé.
  • N'applique pas de restrictions de sandbox filesystem (APIs File System Access non restreintes).

Quand ne PAS l'utiliser

  • Ne pas bloquer totalement le navigateur in-game (feature RP attendue).
  • Ne pas appliquer de patch côté client uniquement : un cheater peut modifier le client. Le serveur doit valider toute interaction.
  • Cette issue est spécifique au client GMod/ Source Engine ; les panels NUI de FiveM (CEF isolé par défaut) ne présentent pas exactement le même vecteur.

Source

  • Projet : Audit sécurité serveur GMod RP — PC factice avec navigateur Internet
  • Contexte : Pentest black-box du panel DHTML in-game, Chromium 86.0.4240.198, GMod/13
  • Validé le : 2026-05-11
  • Finding : Fuite de cookies tiers (3243 bytes), lecture chromium.log (203KB), SteamID exposé dans les logs réseau, persistance localStorage après redémarrage complet.