CSP für Express.js konfigurieren
Content Security Policy in Express.js mit Helmet einrichten — inklusive dynamischer Nonces per Middleware und schrittweiser Rollout von Report-Only zu Enforcement.
Content Security Policy in Express.js
Express.js ist das meistgenutzte Node.js-Framework — und dank Middleware-Architektur ideal für Security Header. Das npm-Paket Helmet ist der De-facto-Standard: Es setzt CSP und weitere Security Header in einer einzigen Middleware. Der Vorteil gegenüber statischen Webservern: Express kann dynamische Nonces pro Request generieren, ohne zusätzliche Module.
CSP ist mit 35 von 166 Punkten der einflussreichste Header im Wolf-Agents Web Security Check. In Express.js lässt sich eine vollständige CSP mit Nonces in unter 20 Zeilen Code umsetzen — Helmet abstrahiert die Komplexität der Header-Syntax und verhindert typische Konfigurationsfehler.
Report-Only mit Helmet
Beginnen Sie immer im Report-Only-Modus. Installieren Sie Helmet und konfigurieren Sie die CSP-Middleware mit reportOnly: true. Im Report-Only-Modus meldet der Browser Violations, ohne Ressourcen zu blockieren.
npm install helmet const helmet = require('helmet');
app.use(helmet.contentSecurityPolicy({
// Report-Only: Browser meldet, blockiert aber nicht
reportOnly: true,
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})); Helmet validiert Direktiven, setzt sinnvolle Defaults und verhindert häufige Fehler wie doppelte Header. Manuell gesetzte res.setHeader()-Aufrufe funktionieren ebenfalls, sind aber fehleranfälliger.
Violations analysieren und CSP anpassen
Öffnen Sie die Browser DevTools (F12) → Console. CSP-Violations erscheinen als Warnungen. Passen Sie die Direktiven in der Helmet-Konfiguration an, bis keine unerwarteten Violations mehr auftreten.
| Violation | Lösung |
|---|---|
| Inline-Script blockiert | Nonce hinzufügen (siehe Schritt 4) |
| Externe Bibliothek blockiert | Domain zu scriptSrc hinzufügen |
| Google Fonts blockiert | fonts.googleapis.com → styleSrc, fonts.gstatic.com → fontSrc |
| WebSocket blockiert | wss://ihre-domain.de → connectSrc |
Enforcement aktivieren
Wenn keine unerwarteten Violations mehr auftreten, entfernen Sie reportOnly: true aus der Helmet-Konfiguration (oder setzen Sie es auf false). Ab diesem Zeitpunkt blockiert der Browser aktiv alle nicht autorisierten Ressourcen.
app.use(helmet.contentSecurityPolicy({
// reportOnly entfernt → Browser blockiert jetzt
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})); reportOnly: true sofort wieder aktivieren — ein Server-Neustart genügt. Dynamische Nonces per Middleware
Für maximale Sicherheit ersetzen Sie 'unsafe-inline' durch dynamische Nonces. Express kann pro Request einen kryptographisch sicheren Nonce erzeugen — dank Middleware-Architektur ohne zusätzliche Pakete. Der Nonce wird in res.locals gespeichert und steht in Templates zur Verfügung.
const crypto = require('crypto');
const helmet = require('helmet');
// Nonce-Middleware: generiert pro Request einen frischen Nonce
app.use((req, res, next) => {
res.locals.nonce = crypto.randomBytes(16).toString('base64');
next();
});
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})); In EJS: <script nonce="<%= nonce %>">. In Pug: script(nonce=nonce). Helmet setzt den Nonce automatisch in den CSP-Header — Sie müssen ihn nur noch in Ihren <script>-Tags referenzieren.
Wie steht Ihre Domain bei Content Security Policy?
Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.