Skip to content

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.

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.

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

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.map

Tenter d’accéder directement au fichier .map :

Terminal window
curl -I https://exemple.com/static/js/main.abc123.js.map

Un code 200 OK confirme que le fichier est accessible.

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”
Terminal window
# Télécharger le fichier .map
curl -O https://exemple.com/static/js/main.abc123.js.map
# Parser le JSON pour lister les fichiers sources embarqués
cat main.abc123.js.map | jq '.sources[]'
# Extraire le contenu d'une source précise
cat main.abc123.js.map | jq '.sourcesContent[0]'

Le champ sourcesContent contient directement le code source original de chaque fichier.

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 bundle

Les routes découvertes dans le routeur permettent ensuite de tester directement les endpoints backend correspondants.

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',
};
ValeurSource map généréeCode source exposéUsage recommandé
falseNonNonProduction
'source-map'Oui (fichier externe)OuiDé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)NonAcceptable si nécessaire
'eval-source-map'Oui (inline)OuiDéveloppement uniquement

hidden-source-map génère le fichier .map sans l’inclure dans le bundle via un commentaire. Le fichier reste accessible si le serveur le sert — ce n’est pas une protection suffisante.

Dans .env.production :

GENERATE_SOURCEMAP=false

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>

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.