Beste Produktionspraktiken: Sicherheit
Der Begriff “production” bezieht sich auf die Stufe im Software-Lebenszyklus, wenn eine Anwendung oder API allgemein für Endbenutzer oder Verbraucher verfügbar ist. Im Gegensatz dazu, in der “development” Bühne, Sie immer noch aktiv schreiben und Test-Code, und die Anwendung ist nicht offen für externen Zugriff. Die entsprechenden Systemumgebungen werden als production bzw. development Umgebungen bezeichnet.
Entwicklungs- und Produktionsumgebungen sind in der Regel unterschiedlich aufgebaut und haben sehr unterschiedliche Anforderungen. Was in der Entwicklung gut ist, kann in der Produktion nicht akzeptabel sein. In einer Entwicklungsumgebung könnte es sein, dass Sie ausführliche Protokollierung von Fehlern zum Debuggen wünschen während das gleiche Verhalten kann zu einem Sicherheitsbedenken in einer Produktionsumgebung werden. Und in der Entwicklung müssen Sie sich keine Sorgen um Skalierbarkeit, Zuverlässigkeit und Leistung machen, während diese Bedenken in der Produktion entscheidend werden.
Note
Wenn Sie glauben, dass Sie eine Sicherheitslücke in Express entdeckt haben, lesen Sie bitte Sicherheits- Richtlinien und Prozeduren.
Best Practices für Express-Anwendungen in der Produktion beinhalten:
- Beste Produktionspraktiken: Sicherheit
- Overview
- Veraltete oder verwundbare Versionen von Express
- Benutze TLS
- Nicht auf Benutzereingabe vertrauen
- Helm verwenden
- Fingerabdruck reduzieren
- Cookies sicher verwenden
- Verhindere Brute-Force-Angriffe gegen Autorisierung
- Vergewissern Sie sich, dass Ihre Abhängigkeiten sicher sind
- Zusätzliche Überlegungen
Veraltete oder verwundbare Versionen von Express nicht verwenden
Express 2.x und 3.x werden nicht mehr gewartet. Sicherheits- und Leistungsprobleme in diesen Versionen werden nicht behoben. Verwenden Sie sie nicht! Wenn Sie nicht auf Version 4 umgezogen sind, folgen Sie der Migrationsanleitung oder überlegen Sie Handelsunterstützungsoptionen.
Vergewissern Sie sich auch, dass Sie keine der verwundbaren Express-Versionen auf der [Seite für Sicherheitsupdates ] verwenden (/en/advanced/security-updates). Wenn Sie dies tun, aktualisieren Sie auf eine der stabilen Releases, vorzugsweise die neuste.
TLS verwenden
Wenn Ihre App sensible Daten behandelt oder übermittelt, verwenden Sie Transport-Layer-Sicherheit (TLS) um die Verbindung und die Daten zu sichern. Diese Technologie verschlüsselt Daten, bevor sie vom Client an den Server gesendet werden, und verhindert so einige häufige (und einfache) Hacks. Obwohl Ajax und POST Anfragen möglicherweise nicht sichtbar sind und im Browser “versteckt” zu sein scheinen, ihr Netzwerkverkehr ist anfällig für Paket-Sniffing und Man-in-the-middle-Angriffe.
Sie können mit der Verschlüsselung Secure Socket Layer (SSL) vertraut sein. TLS ist einfach die nächste Weiterentwicklung von SSL. Mit anderen Worten: Wenn Sie SSL zuvor verwendet haben, sollten Sie ein Upgrade auf TLS in Betracht ziehen. Im Allgemeinen empfehlen wir Nginx mit TLS umzugehen. Für eine gute Referenz zum Konfigurieren von TLS auf Nginx (und anderen Servern) siehe Empfohlene Server-Konfigurationen (Mozilla Wiki).
Ein praktisches Werkzeug, um ein kostenloses TLS-Zertifikat zu erhalten, ist Let’s Encrypt, ein kostenloses und automatisiertes TLS-Zertifikat und offene Zertifizierungsstelle (CA) zur Verfügung gestellt von der Internet Security Research Group (ISRG).
Benutzereingabe nicht vertrauen
Eine der wichtigsten Sicherheitsanforderungen für Webanwendungen ist die korrekte Validierung und Handhabung von Benutzereingaben. Das kommt in vielen Formen, und wir werden hier nicht alle abdecken. Letztlich liegt die Verantwortung für die Validierung und korrekte Handhabung der Benutzereingaben, die Ihre Anwendung akzeptiert, bei Ihnen.
Offene Weiterleitungen verhindern
Ein Beispiel für potenziell gefährliche Benutzereingaben ist eine open redirect, wo eine Anwendung akzeptiert eine URL als Benutzereingabe (oft in der URL-Abfrage, zum Beispiel ”? rl=https://Beispiel. om) und verwendet res.redirectum denlocation` Header und
einen 3xx Status zu setzen.
Eine Anwendung muss überprüfen, dass sie eine Umleitung auf die eingehende URL unterstützt, um zu vermeiden, dass Benutzer an böswillige Links wie Phishing-Websites geschickt werden unter anderem Risiken.
Hier ist ein Beispiel für die Überprüfung von URLs, bevor res.redirect oder res.location:
app.use((req, res) => { try { if (new Url(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`); } } catch (e) { return res.status(400).end(`Invalid url: ${req.query.url}`); } res.redirect(req.query.url);});Helm verwenden
Helmet kann helfen, Ihre App vor einigen bekannten Web-Verwundbarkeiten zu schützen, indem Sie HTTP-Header entsprechend setzen.
Helmet ist eine Middleware-Funktion, die sicherheitsrelevante HTTP-Antwort-Header festlegt. Helm setzt standardmäßig folgende Kopfzeilen:
Content-Security-Policy: Eine mächtige Zulassungsliste dessen, was auf deiner Seite passieren kann, die viele Angriffe mildertCross-Origin-Opener-Policy: Hilft dabei, Ihre Seite zu isolierenCross-Origin-Resource-Policy: Blockiert andere vom Laden deiner Ressourcen Cross-originOrigin-Agent-Cluster: Ändert die Prozess-Isolation in originalbasierteReferrer-Policy: Steuert denRefererHeader- “Strict-Transport-Sicherheit”: Bedeutet Browser, HTTPS vorzuziehen
X-Content-Type-Optionen: Vermeiden MIME SniffingX-DNS-Prefetch-Control: Steuert DNS-VorabholungX-Download-Optionen: Erzwingt Downloads zu speichern (nur im Internet Explorer)X-Frame-Optionen: Legacy-Header, der Clickjacking Angriffe mildertX-Permitted-Cross-Domain-Policies: Kontrolliert Domainübergreifendes Verhalten für Adobe-Produkte wie AcrobatX-Powered-By: Info über den Webserver. Entfernt, weil es bei einfachen Angriffen verwendet werden kannX-XSS-Protection: Legacy-Header, der versucht, XSS-Angriffs, zu mildern, aber die Dinge verschlimmert, also deaktiviert Helm ihn
Jeder Header kann konfiguriert oder deaktiviert werden. Um mehr darüber zu erfahren, gehen Sie bitte auf seine Dokumentations-Website.
Helm wie jedes andere Modul installieren:
$ npm install helmetDann verwenden Sie es in Ihrem Code:
// ...
const helmet = require('helmet');app.use(helmet());
// ...Fingerabdruck verringern
Es kann helfen, eine zusätzliche Sicherheitsschicht zu bieten, um die Fähigkeit von Angreifern zu verringern, die Software zu ermitteln, die ein Server benutzt bekannt als “Fingerabdruck”. Obwohl es selbst kein Sicherheitsproblem ist, verbessert die Reduzierung der Fingerabdrücke einer Anwendung seine allgemeine Sicherheitsauffassung. Server-Software kann durch Quirks Fingerabdrücke in der Art und Weise abgerufen werden, wie sie auf bestimmte Anfragen reagiert, zum Beispiel in den HTTP-Antwort-Headern.
Standardmäßig sendet Express den X-Powered-By Antwort-Header, den Sie
deaktivieren können mit der app.disable() Methode:
app.disable('x-powered-by');Note
Das Deaktivieren des X-Powered-By-Header hindert einen anspruchsvollen Angreifer nicht daran,
zu ermitteln, dass eine App Express ausführt. It may discourage a casual exploit, but there are other ways to
determine an app is running Express.
Express sendet auch eigene formatierte “404 Not Found”-Nachrichten und Formatierungsfehler Antwortmitteilungen. Diese können von geändert werden füge deinen eigenen nicht gefundenen Handler hinzu und deinen eigenen Fehler zu schreiben:
// last app.use calls right before app.listen():
// custom 404app.use((req, res, next) => { res.status(404).send("Sorry can't find that!");});
// custom error handlerapp.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!');});Cookies sicher verwenden
Um sicherzustellen, dass Cookies nicht Ihre App zum Ausnutzen öffnen, verwenden Sie nicht den standardmäßigen Session-Cookie-Namen und setzen Sie die Cookie-Sicherheitsoptionen entsprechend ein.
Es gibt zwei zentrale Middleware-Cookie-Sitzungsmodule:
- express-session, die
express.sessionMiddleware in Express 3.x ersetzt. - cookie-session, die die in Express 3.x integrierte Middleware
express.cookieSessionersetzt.
Der Hauptunterschied zwischen diesen beiden Modulen liegt darin, wie sie Cookie-Sitzungsdaten speichern. Die express-session Middleware speichert Sitzungsdaten auf dem Server; sie speichert die Session-ID nur im Cookie selbst, nicht im Sitzungsdatum. Standardmäßig verwendet er Speicher im Speicher und ist nicht für eine Produktionsumgebung konzipiert. In der Produktion müssen Sie einen skalierbaren Session-Shop einrichten; siehe die Liste der kompatiblen Session-Shops.
Im Gegensatz dazu implementiert cookie-session Middleware Cookie unterstützten Speicher: Es serialisiert die gesamte Sitzung auf das Cookie und nicht nur auf eine Sitzungsschlüssel. Verwenden Sie es nur, wenn Session-Daten relativ klein sind und leicht als primitive Werte kodiert werden (statt Objekte). Obwohl Browser mindestens 4096 Bytes pro Cookie unterstützen sollen, um sicherzustellen, dass Sie das Limit nicht überschreiten, nicht größer als 4093 Bytes pro Domain. Beachten Sie auch, dass die Cookie-Daten für den Kunden sichtbar sind, Wenn es also einen Grund gibt, es sicher oder undurchsichtig zu halten, dann könnte express-session eine bessere Wahl sein.
Nicht den Standard-Sitzungs-Cookie-Namen verwenden
Die Verwendung des Standard-Sitzungs-Cookie-Namens kann Ihre App für Angriffe öffnen. Das Sicherheitsproblem ähnelt X-Powered-By: Ein potenzieller Angreifer kann es verwenden, um den Server und die Zielangriffe entsprechend zu Fingerabdruck zu verwenden.
Um dieses Problem zu vermeiden, verwenden Sie generische Cookie-Namen; zum Beispiel express-session Middleware:
const session = require('express-session');app.set('trust proxy', 1); // trust first proxyapp.use( session({ secret: 's3Cur3', name: 'sessionId', }));Cookie-Sicherheitsoptionen festlegen
Legen Sie die folgenden Cookie-Optionen fest, um die Sicherheit zu verbessern:
secure- Stellt sicher, dass der Browser das Cookie nur über HTTPS sendet.httpOnly- Stellt sicher, dass das Cookie nur über HTTP(S), nicht über Client-JavaScript, gesendet wird. Dies hilft beim Schutz vor Site-übergreifenden Skripting-Attacken.domain- gibt die Domain des Cookie an; verwenden Sie sie um sie mit der Domain des Servers zu vergleichen, auf dem die URL angefordert wird. Wenn sie übereinstimmen, überprüfen Sie als nächstes das Pfad-Attribut.path- zeigt den Pfad des Cookie; verwenden Sie ihn um mit dem Abfragepfad zu vergleichen. Wenn dies und Domäne übereinstimmen, dann senden Sie das Cookie in der Anfrage.expires- verwenden Sie, um das Ablaufdatum für persistente Cookies festzulegen.
Hier ist ein Beispiel mit cookie-session Middleware:
const session = require('cookie-session');const express = require('express');const app = express();
const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hourapp.use( session({ name: 'session', keys: ['key1', 'key2'], cookie: { secure: true, httpOnly: true, domain: 'example.com', path: 'foo/bar', expires: expiryDate, }, }));Brute-Force-Angriffe gegen Autorisierung verhindern
Stellen Sie sicher, dass Login-Endpunkte geschützt sind, um private Daten sicherer zu machen.
Eine einfache und leistungsstarke Technik ist es, Autorisierungsversuche mit zwei Metriken zu blockieren:
- Die Anzahl der aufeinanderfolgenden fehlgeschlagenen Versuche mit dem gleichen Benutzernamen und der gleichen IP-Adresse.
- Die Anzahl fehlgeschlagener Versuche einer IP-Adresse über einen längeren Zeitraum. Zum Beispiel blockieren Sie eine IP-Adresse, wenn sie 100 fehlgeschlagene Versuche an einem Tag macht.
rate-limiter-flexible Paket stellt Werkzeuge zur Verfügung, um diese Technik einfach und schnell zu machen. Du findest ein Beispiel für brutalen Schutz in der Dokumentation
Stellen Sie sicher, dass Ihre Abhängigkeiten sicher sind
Die Verwendung von npm zur Verwaltung der Abhängigkeiten Ihrer Anwendung ist mächtig und komfortabel. Aber die Pakete, die Sie verwenden, können kritische Sicherheitslücken enthalten, die auch Ihre Anwendung betreffen könnten. Die Sicherheit Ihrer App ist nur so stark wie der “schwächste Link” in Ihren Abhängigkeiten.
Seit npm@6 überprüft npm automatisch jede Installationsanforderung. Außerdem kannst du npm audit verwenden, um deinen Abhängigkeitsbaum zu analysieren.
$ npm auditWenn du sicherer bleiben möchtest, bedenke Snyk.
Snyk bietet sowohl ein Kommandozeilenwerkzeug als auch eine Github-Integration, die Ihre Anwendung auf [Snyk’s Open-Source-Verwundbarkeitsdatenbank] (https://snyk.io/vuln/) auf bekannte Verwundbarkeiten in Ihren Abhängigkeiten überprüft. Installieren Sie das CLI wie folgt:
$ npm install -g snyk$ cd your-appVerwenden Sie diesen Befehl, um Ihre Anwendung auf Schwachstellen zu testen:
$ snyk testVermeiden Sie andere bekannte Schwachstellen
Halten Sie Ausschau nach Node Security Project oder Snyk Ankündigungen, die Express oder andere Module, die Ihre App verwendet, beeinflussen können. Im Allgemeinen sind diese Datenbanken ausgezeichnete Ressourcen für Wissen und Werkzeuge rund um die Knotensicherheit.
Schließlich können Express-Apps—wie alle anderen Web-Apps—anfällig für eine Vielzahl webbasierter Angriffe sein. Vertrauen Sie sich mit bekannten Web-Verwundbarkeiten und ergreifen Sie Vorsichtsmaßnahmen, um sie zu vermeiden.
Zusätzliche Überlegungen
Hier sind einige weitere Empfehlungen der ausgezeichneten Node.js Security Checklist. Empfehlen Sie diesen Blog-Beitrag für alle Details zu diesen Empfehlungen:
- Immer die Benutzereingabe filtern und bereinigen, um gegen Site-übergreifendes Skripting (XSS) und Injektionsangriffe zu schützen.
- Verteidigen Sie gegen SQL-Injektionsangriffe durch parametrierte Abfragen oder vorbereitete Anweisungen.
- Benutzen Sie das Open-Source sqlmap Werkzeug, um Verwundbarkeiten in Ihrer App zu erkennen.
- Verwenden Sie die Werkzeuge nmap und sslyze um die Konfiguration Ihrer SSL-Chiffren zu testen, Schlüssel, Neuverhandlung sowie die Gültigkeit Ihres Zertifikats.
- Verwende safe-regex, um sicherzustellen, dass deine regulären Ausdrücke nicht anfällig für reguläre Ausdrucksverweigerung des Dienstes Angriffe sind.