Source Maps in Produktion: Debugging-Hilfe oder versehentlich öffentlich?
Source Maps sind nicht automatisch eine Sicherheitslücke. Aber unbeabsichtigt veröffentlichte Maps können Quellcode, Dateipfade und interne Struktur offenlegen. So prüfen Sie Build, Deployment und Error-Monitoring sauber.
Ihre produktive Website liefert ein minifiziertes JavaScript-Bundle aus. Daneben ist app.js.map erreichbar. In den DevTools erscheinen plötzlich Komponenten-, Datei- und Funktionsnamen, die im gebündelten Code kaum noch erkennbar waren.
Ist das automatisch eine Sicherheitslücke? Nein.
Ist es etwas, das ein Team bewusst entscheiden sollte? Unbedingt.
Source Maps sind ein Debugging-Artefakt. Sie verbinden erzeugten, gebündelten oder minifizierten Code mit den ursprünglichen Quelldateien. ECMA-426 standardisiert dieses Format ausdrücklich für Source-Level-Debugging und die Deobfuskation von Stack Traces. Genau deshalb sind Source Maps für Produktion wertvoll: Ein Fehler in chunk-8f31c.js:1:18452 kann wieder auf eine verständliche Zeile in einer React-, TypeScript- oder anderen Quelldatei zurückgeführt werden.
Das Problem entsteht nicht durch die Existenz der Maps. Es entsteht, wenn niemand weiß, ob sie öffentlich sein sollen, welche Inhalte sie enthalten und ob der Deployment-Prozess diese Entscheidung zuverlässig durchsetzt.
Mythos: "Source Maps verraten unseren geheimen Code"
Clientseitiger JavaScript-Code ist grundsätzlich kein Geheimnis. Der Browser muss ihn herunterladen, um ihn auszuführen. Minifizierung erschwert das Lesen, ist aber keine Zugriffskontrolle.
Source Maps können diese Analyse jedoch erheblich vereinfachen. Abhängig von der erzeugten Map stehen darin unter anderem:
- ursprüngliche Dateinamen und Pfade,
- Modul- und Verzeichnisstruktur,
- Zuordnungen von generierten zu ursprünglichen Positionen,
- Namen von Funktionen oder Variablen,
- und optional der ursprüngliche Quelltext selbst über
sourcesContent.
Wenn sourcesContent enthalten ist, muss ein Browser die ursprünglichen Dateien nicht separat abrufen: Die Map kann den Quelltext direkt mitbringen.
Das macht eine öffentliche Source Map nicht automatisch zu einem Incident. Aber es kann Informationen preisgeben, die das Team bewusst nicht als öffentliches Entwicklungsartefakt ausliefern wollte: Kommentare, interne Dateinamen, Feature-Bezeichnungen, alte Pfade oder die Struktur nicht veröffentlichter Module.
Und eine wichtige Grenze bleibt bestehen: Ein echtes Secret darf ohnehin nie im Client-Build landen. Wenn ein API-Token, Passwort oder anderer geheimer Wert durch den Build in Browsercode oder eine Source Map geraten ist, ist die richtige Reaktion nicht nur, die .map-Datei zu löschen. Der Wert muss widerrufen oder rotiert und die Client-/Server-Grenze korrigiert werden.
Drei Produktionsmodelle – und alle können legitim sein
Es gibt nicht die eine richtige Source-Map-Konfiguration für jede Website. Entscheidend ist der Zweck.
1. Vollständig öffentliche Source Maps
Das kann bewusst sinnvoll sein, etwa bei Open-Source-Anwendungen oder wenn Browser-Debugging ausdrücklich gewünscht ist. Die Entscheidung sollte dann dokumentiert sein.
Bei Next.js sind Browser-Source-Maps für Production Builds standardmäßig deaktiviert. Wird productionBrowserSourceMaps aktiviert, schreibt Next.js die Maps in dasselbe Ausgabeverzeichnis wie die JavaScript-Dateien und liefert sie auf Anfrage aus. Das ist ein sehr klares Beispiel dafür, dass die Option nicht nur "bessere Stack Traces" bedeutet, sondern eine Änderung dessen, was öffentlich ausgeliefert wird.
2. Source Maps nur für Error-Monitoring
Das ist für viele kommerzielle Websites der sinnvollste Weg. Der Build erzeugt präzise Maps, lädt sie während CI/CD zu einem Fehlertracking-Dienst hoch und veröffentlicht sie nicht auf dem Webserver.
webpack nennt dafür hidden-source-map als möglichen Produktionsmodus: Die Map wird erzeugt, aber das Bundle erhält keinen Verweis darauf. webpack warnt zugleich, dass diese Maps bei reiner Nutzung für Error-Reporting nicht auf dem Webserver bereitgestellt werden sollten.
Wichtig: "hidden" bedeutet nur, dass kein Source-Map-Verweis in das Bundle geschrieben wird. Wenn Ihre Deployment-Pipeline trotzdem jede .map-Datei in den öffentlichen Bucket kopiert, ist sie weiterhin abrufbar.
Sentry dokumentiert genau deshalb einen typischen CI-Pfad: Maps erzeugen, hochladen und anschließend über die Build-Plugin-Konfiguration löschen oder den Webserver so konfigurieren, dass .js.map nicht öffentlich ausgeliefert wird.
3. Maps ohne eingebetteten Quelltext
webpack bietet mit nosources-source-map eine Variante, bei der sourcesContent nicht enthalten ist. Das kann Stack-Trace-Zuordnung ermöglichen, ohne den Originalquelltext direkt in der Map mitzuliefern.
Das ist aber kein vollständiger Unsichtbarkeitsmodus. webpack weist ausdrücklich darauf hin, dass Dateinamen und Struktur weiterhin sichtbar sein können.
Die Entscheidung lautet also nicht einfach "Map oder keine Map". Sie lautet: Wer braucht welche Debugging-Information, und wo darf sie liegen?
Der zweite blinde Fleck: Die Map passt nicht zum Release
Eine Source Map ist nur dann nützlich, wenn sie zum exakt ausgelieferten Artefakt gehört.
Stellen Sie sich vor:
- Release A erzeugt
app.abc123.jsund die passende Map. - Release B verändert den Code.
- Das CDN liefert bereits Bundle B aus, im Error-Monitoring liegen aber nur die Maps von A.
- Ein Fehler wird deobfuskiert – und zeigt auf eine Zeile, die in diesem Release gar nicht mehr stimmt.
Das Ergebnis ist schlimmer als ein unlesbarer Stack Trace, weil es plausibel aussieht und Entwickler in die falsche Richtung schicken kann.
Ein belastbarer Prozess bindet Source Maps deshalb an das tatsächlich deployte Build-Artefakt. Bei modernen Error-Monitoring-Setups geschieht das über Release-Metadaten, Debug-IDs oder vergleichbare Zuordnungen. Entscheidend ist organisatorisch: Upload und Deployment gehören in denselben reproduzierbaren Release-Pfad.
Maps manuell irgendwann nach einem Deployment hochzuladen ist kein zuverlässiges Verfahren.
Sieben Red Flags in einem Source-Map-Audit
1. Niemand weiß, ob Produktion Maps erzeugt
Die Einstellung steckt irgendwo in Framework-, Bundler- oder Plugin-Konfiguration und wurde seit dem Relaunch nicht mehr geprüft.
2. .map-Dateien landen automatisch im öffentlichen Artefakt
CI kopiert das komplette Build-Verzeichnis auf CDN, Object Storage oder Webserver. Es gibt keine bewusste Include-/Exclude-Regel.
3. hidden-source-map wird mit "nicht öffentlich" verwechselt
Der Referenzkommentar fehlt, aber die Datei ist unter einem erratbaren Pfad trotzdem erreichbar.
4. sourcesContent wird nie kontrolliert
Das Team prüft nur, ob eine Map existiert, nicht welche Quelldateien und Inhalte darin eingebettet sind.
5. Error-Monitoring erhält Maps aus einem anderen Build
Lokaler Build, CI-Build und Produktion verwenden unterschiedliche Flags, Umgebungsvariablen oder Minimizer. Die hochgeladene Map ist nicht identisch mit dem veröffentlichten Bundle.
6. Alte Maps bleiben unbegrenzt im CDN
Ein neues Deployment entfernt die aktuelle Map, aber historische gehashte Assets bleiben weiterhin öffentlich erreichbar. Bei einer bewussten Policy muss auch die Retention alter Releases betrachtet werden.
7. Ein Leak wird durch Löschen statt Rotieren "behoben"
Wenn tatsächlich ein Secret in einem Build-Artefakt war, reicht das Entfernen der Datei nicht. Sobald ein Wert öffentlich abrufbar war, muss davon ausgegangen werden, dass er kopiert worden sein könnte.
Ein praktischer Audit in 30 Minuten
Schritt 1: Build-Konfiguration lesen
Suchen Sie nach Framework- und Bundleroptionen wie:
productionBrowserSourceMaps,devtool,sourcemap,hidden-source-map,nosources-source-map,- Source-Map-Plugins Ihres Error-Monitorings.
Dokumentieren Sie nicht nur den Wert, sondern die gewünschte Policy: öffentlich, nur Monitoring oder vollständig deaktiviert.
Schritt 2: Das reale Produktionsartefakt untersuchen
Nach einem Produktions-Build sollten Sie wissen:
- Welche
.map-Dateien wurden erzeugt? - Welche Bundles enthalten
sourceMappingURL? - Enthalten die Maps
sourcesContent? - Welche Dateinamen und Pfade stehen unter
sources? - Werden Browser- und Server-Maps getrennt behandelt?
Prüfen Sie das Artefakt, das tatsächlich deployed wird – nicht nur das lokale Entwicklungsverzeichnis.
Schritt 3: Von außen testen
Öffnen Sie eine produktive JavaScript-Datei und prüfen Sie, ob ein Source-Map-Verweis vorhanden ist. Versuchen Sie anschließend kontrolliert, die zugehörige .map-Datei abzurufen.
Wenn Ihre Policy "privat" lautet, sollte die Map nicht einfach mit 200 OK öffentlich zurückkommen.
Verlassen Sie sich nicht nur auf den fehlenden Kommentar. Ein bekanntes oder erratbares Asset kann auch ohne Referenz abrufbar sein.
Schritt 4: Error-Monitoring verifizieren
Lösen Sie in einer kontrollierten Produktions- oder Preview-Umgebung einen bekannten JavaScript-Fehler aus. Prüfen Sie, ob der Stack Trace auf die erwartete Quelldatei und Zeile zeigt.
So testen Sie gleichzeitig:
- ob Maps hochgeladen wurden,
- ob sie zum Release passen,
- ob Release-/Debug-Metadaten stimmen,
- und ob das Monitoring nicht nur "irgendwelche Dateien" besitzt.
Schritt 5: Alte Releases prüfen
CDNs und Object Storage behalten gehashte Assets oft bewusst lange. Das ist für Caching sinnvoll. Wenn Ihre neue Policy Source Maps nicht mehr öffentlich vorsieht, sollten Sie entscheiden, was mit alten Maps passiert und ob sie noch gebraucht werden.
Source Maps als CI-Regel statt Bauchgefühl
Die nachhaltigste Lösung ist nicht, einmal manuell .map-Dateien zu löschen. Machen Sie die Entscheidung testbar.
Ein Release-Check kann beispielsweise:
- nach unerwarteten
.map-Dateien im Public-Artefakt suchen, sourceMappingURLin produktiven Bundles prüfen,- den Upload zum Error-Monitoring vor dem Deployment verifizieren,
- den Build abbrechen, wenn Maps laut Policy öffentlich werden würden,
- Browser- und Server-Artefakte getrennt behandeln,
- nach sensiblen Token-Mustern in Build-Ausgaben suchen,
- und einen Smoke-Test gegen die produktive Asset-URL ausführen.
So wird aus "Ich glaube, Next.js liefert das nicht aus" eine reproduzierbare Eigenschaft des Release-Prozesses.
Was Website-Pflichtencheck prüfen würde
Ein technischer Source-Map-Check kann untersuchen:
- tatsächlich ausgelieferte JavaScript- und CSS-Artefakte,
- öffentliche
.map-URLs undsourceMappingURL-Referenzen, sources,sourcesContentund sichtbare Projektstruktur,- Next.js-, webpack-, Vite- oder andere Bundler-Konfiguration,
- Unterschiede zwischen Development, Preview und Production,
- Source-Map-Uploads zu Error-Monitoring-Systemen,
- Zuordnung zum richtigen Release,
- CDN- und Storage-Retention alter Maps,
- Build-Artefakt-Scanning und CI-Regeln,
- und den Umgang mit versehentlich ausgelieferten Zugangsdaten.
Das Ziel ist nicht, Source Maps pauschal zu verbieten. Gute Fehlerdiagnose in Produktion ist wertvoll. Das Ziel ist, Debugging-Artefakte genauso bewusst zu behandeln wie Logs, Build-Ausgaben und Deployments.
Wenn Ihre Source Maps öffentlich sind, sollte das eine Entscheidung sein – kein Nebenprodukt davon, dass jemand vor zwei Jahren einen Build-Schalter aktiviert hat.