Webpack : exposition des source maps en production
Beaucoup d’applications web utilisent encore Webpack pour bundler leur code JavaScript. Mal configuré, un build de production peut embarquer les source maps et exposer le code source original directement dans le navigateur du visiteur.
Le problème
Section titled “Le problème”Webpack intègre une option devtool qui contrôle la génération des source maps. Ces fichiers .map servent au débogage : ils font le lien entre le code minifié livré au navigateur et le code source original.
En développement, c’est utile. En production, c’est une fuite de code source.
Ce qu’un attaquant peut récupérer
Section titled “Ce qu’un attaquant peut récupérer”En accédant aux fichiers .map exposés, on peut reconstruire :
- le code source complet des composants (React, Vue, Angular…)
- le routeur et ses routes internes, y compris celles non affichées dans l’interface
- les appels API et les endpoints backend
- des secrets embarqués : clés API, tokens, URLs d’environnements internes
- la logique métier qui devrait rester côté serveur
Détecter l’exposition
Section titled “Détecter l’exposition”Vérifier les en-têtes et les fichiers .map
Section titled “Vérifier les en-têtes et les fichiers .map”Un bundle exposant ses source maps contiendra en bas du fichier JavaScript une ligne du type :
//# sourceMappingURL=main.abc123.js.mapTenter d’accéder directement au fichier .map :
curl -I https://exemple.com/static/js/main.abc123.js.mapUn code 200 OK confirme que le fichier est accessible.
Lister les bundles via les DevTools
Section titled “Lister les bundles via les DevTools”Dans les DevTools du navigateur (Chrome / Firefox), onglet Sources : si les source maps sont chargées, l’arborescence des fichiers source originaux apparaît directement, avec les noms de fichiers, les composants, et le code non minifié.
Télécharger et reconstruire le code source
Section titled “Télécharger et reconstruire le code source”# Télécharger le fichier .mapcurl -O https://exemple.com/static/js/main.abc123.js.map
# Parser le JSON pour lister les fichiers sources embarquéscat main.abc123.js.map | jq '.sources[]'
# Extraire le contenu d'une source précisecat main.abc123.js.map | jq '.sourcesContent[0]'Le champ sourcesContent contient directement le code source original de chaque fichier.
Ce qu’on peut trouver concrètement
Section titled “Ce qu’on peut trouver concrètement”En explorant les sources reconstruites, les éléments à cibler en priorité :
src/├── router/│ └── index.js # routes internes, routes d'administration├── api/│ └── client.js # URLs des endpoints, tokens d'authentification├── config/│ └── env.js # variables d'environnement embarquées au build└── components/ └── Admin.vue # composants cachés dans l'UI mais présents dans le bundleLes routes découvertes dans le routeur permettent ensuite de tester directement les endpoints backend correspondants.
Remédiation
Section titled “Remédiation”Désactiver les source maps en production
Section titled “Désactiver les source maps en production”Dans webpack.config.js :
module.exports = { mode: 'production', devtool: false, // aucune source map générée};Ou en conditionnant selon l’environnement :
module.exports = { devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',};Options devtool disponibles
Section titled “Options devtool disponibles”| Valeur | Source map générée | Code source exposé | Usage recommandé |
|---|---|---|---|
false | Non | Non | Production |
'source-map' | Oui (fichier externe) | Oui | Développement uniquement |
'hidden-source-map' | Oui (non référencée) | Oui si accédée | À éviter en production |
'nosources-source-map' | Oui (sans code source) | Non | Acceptable si nécessaire |
'eval-source-map' | Oui (inline) | Oui | Développement uniquement |
hidden-source-mapgénère le fichier.mapsans l’inclure dans le bundle via un commentaire. Le fichier reste accessible si le serveur le sert — ce n’est pas une protection suffisante.
Pour les projets Create React App
Section titled “Pour les projets Create React App”Dans .env.production :
GENERATE_SOURCEMAP=falsePour Vue CLI
Section titled “Pour Vue CLI”Dans vue.config.js :
module.exports = { productionSourceMap: false,};Bloquer l’accès côté serveur (défense en profondeur)
Section titled “Bloquer l’accès côté serveur (défense en profondeur)”Si des fichiers .map ont déjà été déployés, bloquer leur accès au niveau du serveur web :
Nginx :
location ~* \.map$ { deny all; return 404;}Apache (.htaccess) :
<FilesMatch "\.map$"> Require all denied</FilesMatch>À retenir
Section titled “À retenir”Désactiver les source maps lors d’un build de production est la première mesure à appliquer avant tout déploiement d’une application front-end. Le coût est nul, la surface d’attaque réduite est significative.
Ne jamais supposer qu’un fichier non référencé dans l’interface est inaccessible : si le serveur le sert, un attaquant peut le trouver.