Heim > Web-Frontend > js-Tutorial > Sichern Ihrer Node.js-Anwendung: Ein umfassender Leitfaden

Sichern Ihrer Node.js-Anwendung: Ein umfassender Leitfaden

Patricia Arquette
Freigeben: 2024-12-08 14:27:10
Original
355 Leute haben es durchsucht

Securing Your Node.js Application: A Comprehensive Guide

In der heutigen digitalen Landschaft ist die Sicherung Ihrer Node.js-Anwendung von größter Bedeutung. Von Weltmarktführern wie Netflix und Uber bis hin zu Start-ups, die das nächste große Ding entwickeln: Node.js unterstützt einige der anspruchsvollsten und leistungsstärksten Anwendungen. Allerdings können Schwachstellen in Ihrer Anwendung zu unbefugtem Zugriff, Datenschutzverletzungen und einem Vertrauensverlust der Benutzer führen.

Dieser Leitfaden kombiniert praktische Sicherheitspraktiken mit Schlüsselkonzepten aus dem OWASP Web Security Testing Guide (WSTG), um Ihnen bei der Stärkung Ihrer Node.js-Anwendung zu helfen. Unabhängig davon, ob Sie Echtzeitvorgänge verwalten oder auf Millionen von Benutzern skalieren, stellt diese umfassende Ressource sicher, dass Ihre Anwendung sicher, zuverlässig und belastbar bleibt.


Informationsbeschaffung (WSTG-INFO)

Das Sammeln von Informationen ist oft der erste Schritt, den ein Angreifer unternimmt, um mehr über Ihre Anwendung zu erfahren. Je mehr Informationen sie sammeln können, desto einfacher wird es für sie, Schwachstellen zu identifizieren und auszunutzen.

Typische Express.js-Serverkonfiguration und Fingerabdruck

Express.js enthält standardmäßig Einstellungen, die unbeabsichtigt Informationen über Ihren Server preisgeben können. Ein häufiges Beispiel ist der X-Powered-By-HTTP-Header, der angibt, dass Ihre Anwendung Express verwendet.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

In diesem Setup enthält jede HTTP-Antwort den X-Powered-By: Express-Header.

Problem:

  • Fingerprinting: Angreifer können diesen Header verwenden, um festzustellen, welche Technologien Sie verwenden. Wenn sie wissen, dass Sie Express verwenden, können sie Angriffe auf bekannte Schwachstellen in bestimmten Versionen von Express oder Node.js zuschneiden.

Abhilfe:

Deaktivieren Sie diesen Header, um es Angreifern zu erschweren, einen Fingerabdruck auf Ihrem Server zu erhalten.

Verbesserter Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Verbesserte Schadensbegrenzung mit Helm:

Ein besserer Ansatz ist die Verwendung der Helm-Middleware, die verschiedene HTTP-Header festlegt, um die Sicherheit Ihrer App zu verbessern.

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Warum einen Helm verwenden?

  • Umfassende Sicherheits-Header: Helmet legt mehrere HTTP-Header fest, die dazu beitragen, Ihre App vor bekannten Web-Schwachstellen zu schützen.
  • Benutzerfreundlichkeit: Mit nur einer Zeile verbessern Sie den Sicherheitsstatus Ihrer Anwendung erheblich.

Testen des Konfigurations- und Bereitstellungsmanagements (WSTG-CONF)

Konfigurations- und Bereitstellungsmanagement sind kritische Aspekte der Anwendungssicherheit. Fehlkonfigurationen können als offene Türen für Angreifer dienen.

Laufen im Entwicklungsmodus in der Produktion

Wenn Sie Ihre Anwendung im Entwicklungsmodus auf einem Produktionsserver ausführen, können detaillierte Fehlermeldungen und Stack-Traces angezeigt werden.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

In diesem Setup werden detaillierte Fehlermeldungen an den Client gesendet.

Problem:

  • Informationsleck: Detaillierte Fehlermeldungen und Stack-Traces können vertrauliche Informationen über die Struktur, Abhängigkeiten und Dateipfade Ihrer Anwendung preisgeben.
  • Erleichtert die Ausnutzung:Angreifer können diese Informationen nutzen, um potenzielle Schwachstellen zu identifizieren und gezielte Angriffe durchzuführen.

Abhilfe:

Setzen Sie NODE_ENV auf „Produktion“ und verwenden Sie generische Fehlermeldungen in der Produktion.

Verbesserter Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Best Practices:

  • Umgebungsvariablen richtig einstellen: Stellen Sie sicher, dass NODE_ENV in Ihrer Produktionsumgebung auf „Produktion“ gesetzt ist.
  • Interne Protokollierung: Fehler intern zu Debugging-Zwecken protokollieren, ohne dem Endbenutzer Details preiszugeben.

Verwendung von Standard- oder schwachen Anmeldeinformationen

Die Verwendung standardmäßiger oder schwacher Anmeldeinformationen, wie z. B. eines einfachen geheimen Schlüssels zum Signieren von JSON Web Tokens (JWTs), ist ein häufiger Sicherheitsfehler.

Beispiel für anfälligen Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Schwacher Geheimschlüssel: Durch die Verwendung einer einfachen oder gebräuchlichen Zeichenfolge wie „geheim“ können Angreifer den Schlüssel leicht erraten oder brutal erzwingen.
  • Hardcodierte Geheimnisse: Das Speichern von Geheimnissen direkt in Ihrem Code erhöht das Risiko einer Offenlegung, wenn Ihre Codebasis kompromittiert wird.
  • Token-Fälschung: Angreifer, die Ihren geheimen Schlüssel kennen, können gültige JWTs fälschen und sich so unbefugten Zugriff verschaffen.

Abhilfe:

Verwenden Sie einen starken, sicheren Geheimschlüssel und bewahren Sie ihn sicher auf.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Best Practices:

  • Umgebungsvariablen: Übergeben Sie keine Geheimnisse an die Versionskontrolle. Verwenden Sie Umgebungsvariablen oder Konfigurationsdateien, die nicht in die Quellcodeverwaltung eingecheckt sind.
  • Geheimnisse rotieren: Implementieren Sie einen Prozess, um Geheimnisse regelmäßig zu rotieren.
  • Konfiguration validieren: Stellen Sie sicher, dass alle erforderlichen Umgebungsvariablen während des Anwendungsstarts festgelegt werden.

Identitätsmanagementtests (WSTG-IDNT)

Identitätsmanagement ist entscheidend für den Schutz von Benutzerkonten und die Verhinderung unbefugten Zugriffs.

Schwache Benutzernamenrichtlinien und Kontoaufzählung

Das Zulassen schwacher Benutzernamen und die Bereitstellung spezifischer Fehlermeldungen kann zu Kontoaufzählungsangriffen führen.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Schwache Benutzernamen: Das Zulassen kurzer oder einfacher Benutzernamen erhöht das Risiko einer Kontokompromittierung.
  • Kontoaufzählung: Spezifische Fehlermeldungen können Angreifern dabei helfen, gültige Benutzernamen zu ermitteln.

Abhilfe:

Implementieren Sie die Validierung des Benutzernamens und verwenden Sie generische Fehlermeldungen.

Verbesserter Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Benutzernamensvalidierung: Stellt sicher, dass Benutzernamen bestimmte Kriterien erfüllen, und reduziert so schwache Einträge.
  • Allgemeine Fehlermeldungen: Verhindern Sie, dass Angreifer durch Fehlerantworten gültige Benutzernamen identifizieren.

Authentifizierungstests (WSTG-ATHN)

Authentifizierungsmechanismen sind für die Überprüfung von Benutzeridentitäten und die Verhinderung unbefugten Zugriffs von entscheidender Bedeutung.

Brute-Force-Angriffe auf Passwörter und 2FA

Mangelnde Schutzmaßnahmen ermöglichen es Angreifern, Passwörter oder 2FA-Codes durch wiederholte Versuche zu erraten.

Beispiel für anfälligen Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Unbegrenzte Anmeldeversuche:Angreifer können wiederholt verschiedene Passwörter oder 2FA-Codes ausprobieren.
  • Schwache 2FA-Implementierung: Statische oder vorhersehbare 2FA-Codes sind anfällig.

Abhilfe:

Implementieren Sie eine Ratenbegrenzung und verbessern Sie die 2FA-Sicherheit.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Zusätzliche Maßnahmen:

  • Verwenden Sie CAPTCHA nach fehlgeschlagenen Anmeldeversuchen:Führen Sie CAPTCHA nach mehreren fehlgeschlagenen Anmeldeversuchen ein, um menschliche Benutzer zu verifizieren.
  • Verwenden Sie TOTP für 2FA:Verwenden Sie zeitbasierte Einmalpasswörter für dynamische und sichere 2FA-Codes.

Erklärung:

  • Ratenbegrenzung: Reduziert das Risiko automatisierter Angriffe durch Begrenzung der Anmeldeversuche.
  • Erweiterte 2FA: Zeitbasierte Codes verbessern die Sicherheit gegenüber statischen Codes.

Autorisierungsprüfung (WSTG-ATHZ)

Autorisierung stellt sicher, dass Benutzer nur auf die Ressourcen zugreifen, die sie verwenden dürfen, und verhindert so unbefugte Aktionen.

Unsichere direkte Objektreferenzen (IDOR)

Benutzer können auf nicht autorisierte Ressourcen zugreifen, indem sie Kennungen in Anfragen manipulieren.

Beispiel für anfälligen Code:

// app.js
const express = require('express');
const app = express();

// Your routes here

// Error handling middleware
if (app.get('env') === 'production') {
  // Production error handler
  app.use((err, req, res, next) => {
    // Log the error internally
    console.error(err);
    res.status(500).send('An unexpected error occurred.');
  });
} else {
  // Development error handler (with stack trace)
  app.use((err, req, res, next) => {
    res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}
`); }); } app.listen(3000);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Unberechtigter Zugriff: Benutzer können auf Daten zugreifen, die sie nicht haben sollten, indem sie den orderId-Parameter ändern.

Abhilfe:

Bestätigen Sie den Ressourcenbesitz, bevor Sie Zugriff gewähren.

Verbesserter Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Eigentümerüberprüfung: Stellt sicher, dass die angeforderte Ressource dem authentifizierten Benutzer gehört.
  • Zugriffskontrolle: Verhindert, dass Benutzer durch Manipulation von Anforderungsparametern auf die Daten anderer zugreifen.

Sitzungsverwaltungstests (WSTG-SESS)

Sitzungsverwaltung ist entscheidend für die Aufrechterhaltung des Benutzerstatus und die Gewährleistung sicherer Interaktionen.

Tokens ohne Ablaufzeit

Token, die niemals ablaufen, stellen ein Sicherheitsrisiko dar, wenn sie kompromittiert werden.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Dauerhafte Token:Tokens ohne Ablaufdatum bleiben auf unbestimmte Zeit gültig, was das Zeitfenster für Missbrauch vergrößert.

Abhilfe:

Legen Sie eine Ablaufzeit für Token fest.

Verbesserter Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Token-Ablauf: Begrenzt die Gültigkeitsdauer und verringert so das Risiko, wenn ein Token kompromittiert wird.
  • Best Practice für Sicherheit: Regelmäßige Token-Erneuerung erhöht die allgemeine Sicherheit.

Unsichere Token-Speicherung

Durch das Speichern von Tokens in localStorage sind sie Cross-Site-Scripting (XSS)-Angriffen ausgesetzt.

Beispiel für anfälligen Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Clientseitige Gefährdung: Schädliche Skripte können auf localStorage zugreifen, Token stehlen und Sitzungen kapern.

Abhilfe:

Verwenden Sie reine HTTP-Cookies, um Token sicher zu speichern.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Your routes here

// Error handling middleware
if (app.get('env') === 'production') {
  // Production error handler
  app.use((err, req, res, next) => {
    // Log the error internally
    console.error(err);
    res.status(500).send('An unexpected error occurred.');
  });
} else {
  // Development error handler (with stack trace)
  app.use((err, req, res, next) => {
    res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}
`); }); } app.listen(3000);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Nur ​​HTTP-Cookies:Für JavaScript nicht zugänglich, wodurch XSS-Risiken gemindert werden.
  • Sichere und SameSite-Flags: Verbessern Sie den Schutz vor Man-in-the-Middle- und Cross-Site-Request-Forgery-Angriffen.

Eingabevalidierungstests (WSTG-INPV)

Eingabevalidierung stellt sicher, dass vom Benutzer bereitgestellte Daten sicher und erwartet sind, und verhindert Injektionsangriffe.

Fehlende Eingabevalidierung

Das Akzeptieren und Verarbeiten von Benutzereingaben ohne Validierung kann zu Sicherheitslücken führen.

Beispiel für anfälligen Code:

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

// Weak secret key
const SECRET_KEY = 'secret';

app.post('/login', (req, res) => {
  // Authenticate user (authentication logic not shown)
  const userId = req.body.userId;

  // Sign the JWT with a weak secret
  const token = jwt.sign({ userId }, SECRET_KEY);
  res.json({ token });
});

app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];

  try {
    // Verify the token using the weak secret
    const decoded = jwt.verify(token, SECRET_KEY);
    res.send('Access granted to protected data');
  } catch (err) {
    res.status(401).send('Unauthorized');
  }
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Injection-Angriffe: Nicht validierte Eingaben können zu SQL-Injection, NoSQL-Injection oder anderen Code-Injection-Angriffen führen.

Abhilfe:

Validieren und bereinigen Sie alle Benutzereingaben.

Verbesserter Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Eingabevalidierung:Überprüft, ob die Eingabe die erwarteten Kriterien erfüllt.
  • Eingabebereinigung:Entfernt oder maskiert potenziell schädliche Zeichen.
  • Sichere Datenbankabfragen: Die Verwendung parametrisierter Abfragen verhindert Injektionsangriffe.

Testen zur Fehlerbehandlung (WSTG-ERRH)

Eine ordnungsgemäße Fehlerbehandlung vermeidet die Offenlegung vertraulicher Informationen und verbessert die Benutzererfahrung.

Sensible Fehlerinformationen offenlegen

Detaillierte Fehlermeldungen können Angreifern Systeminterna offenbaren.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Offenlegung von Informationen:Angreifer können Einblicke in die Struktur Ihrer Anwendung und potenzielle Schwachstellen gewinnen.

Abhilfe:

Verwenden Sie generische Fehlermeldungen und protokollieren Sie detaillierte Fehler intern.

Verbesserter Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Interne Protokollierung: Hält detaillierte Fehlerinformationen sicher.
  • Benutzerfreundliche Nachrichten: Stellt eine allgemeine Nachricht bereit, ohne vertrauliche Details preiszugeben.

Testen auf schwache Kryptographie (WSTG-CRYP)

Kryptographie schützt sensible Daten; Die Verwendung schwacher kryptografischer Praktiken untergräbt die Sicherheit.

Verwendung unsicherer Hashing-Algorithmen

Das Hashing von Passwörtern mit veralteten Algorithmen ist unsicher.

Beispiel für anfälligen Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Schwaches Hashing: Algorithmen wie MD5 und SHA-1 sind anfällig für Kollisionsangriffe und sollten nicht für Passwort-Hashing verwendet werden.

Abhilfe:

Verwenden Sie einen starken Hashing-Algorithmus, der für Passwörter entwickelt wurde.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Your routes here

// Error handling middleware
if (app.get('env') === 'production') {
  // Production error handler
  app.use((err, req, res, next) => {
    // Log the error internally
    console.error(err);
    res.status(500).send('An unexpected error occurred.');
  });
} else {
  // Development error handler (with stack trace)
  app.use((err, req, res, next) => {
    res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}
`); }); } app.listen(3000);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Bcrypt: Eine robuste Hashing-Funktion, die Salting und mehrere Hashing-Runden beinhaltet.
  • Passwortsicherheit: Macht es Angreifern rechnerisch unmöglich, Passwörter zurückzuentwickeln.

Geheime Schlüssel fest kodieren

Das Speichern von Geheimnissen direkt im Code erhöht das Risiko einer Offenlegung.

Beispiel für anfälligen Code:

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

// Weak secret key
const SECRET_KEY = 'secret';

app.post('/login', (req, res) => {
  // Authenticate user (authentication logic not shown)
  const userId = req.body.userId;

  // Sign the JWT with a weak secret
  const token = jwt.sign({ userId }, SECRET_KEY);
  res.json({ token });
});

app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];

  try {
    // Verify the token using the weak secret
    const decoded = jwt.verify(token, SECRET_KEY);
    res.send('Access granted to protected data');
  } catch (err) {
    res.status(401).send('Unauthorized');
  }
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Secret Exposure: Wenn die Codebasis kompromittiert ist, können hartcodierte Geheimnisse leicht extrahiert werden.

Abhilfe:

Speichern Sie Geheimnisse in Umgebungsvariablen oder sicheren Konfigurationsdateien.

Verbesserter Code:

const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Umgebungsvariablen: Halten Sie Geheimnisse aus der Codebasis und den Versionskontrollsystemen fern.
  • Sicherheitspraktiken: Reduziert das Risiko einer versehentlichen Exposition.

Geschäftslogiktests (WSTG-BUSL)

Geschäftslogik Schwachstellen treten auf, wenn Anwendungsflüsse auf unbeabsichtigte Weise manipuliert werden können.

Missbrauch von Massenoperationen

Uneingeschränkter Datenbetrieb kann zu Leistungsproblemen oder Datenlecks führen.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Denial of Service (DoS):Große Datenexporte können Serverressourcen erschöpfen.
  • Datenleck: Uneingeschränkter Zugriff kann zur Offenlegung sensibler Informationen führen.

Abhilfe:

Implementieren Sie Paginierung und Zugriffskontrollen.

Verbesserter Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Paginierung: Steuert die Menge der zurückgegebenen Daten und verhindert so eine Ressourcenerschöpfung.
  • Zugriffskontrolle: Stellt sicher, dass Benutzer nur auf ihre eigenen Daten zugreifen können.

Clientseitiges Testen (WSTG-CLNT)

Der Schutz vor clientseitigen Schwachstellen ist unerlässlich, um Benutzer vor Angriffen wie Cross-Site Scripting (XSS) zu schützen.

Benutzereingaben mithilfe der xss-Bibliothek entgehen

Unsachgemäßer Umgang mit Benutzereingaben in clientseitigen Skripten kann zu XSS-Angriffen führen.

Beispiel für anfälligen Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Unsichere DOM-Manipulation: Das Einfügen nicht bereinigter Benutzereingaben in innerHTML ermöglicht die Ausführung schädlicher Skripte.

Abhilfe:

Verwenden Sie die XSS-Bibliothek, um Benutzereingaben vor dem Rendern zu bereinigen.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Your routes here

// Error handling middleware
if (app.get('env') === 'production') {
  // Production error handler
  app.use((err, req, res, next) => {
    // Log the error internally
    console.error(err);
    res.status(500).send('An unexpected error occurred.');
  });
} else {
  // Development error handler (with stack trace)
  app.use((err, req, res, next) => {
    res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}
`); }); } app.listen(3000);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Eingabebereinigung: Die XSS-Bibliothek bereinigt Eingaben, indem sie potenziell gefährliche Inhalte maskiert oder entfernt.
  • Skriptausführung verhindern: Neutralisiert schädliche Skripte und verhindert deren Ausführung im Browser.

Best Practices:

  • Verwenden Sie textContent, wenn möglich: Durch das Zuweisen von Benutzereingaben zu textContent wird dieser als einfacher Text behandelt.
const express = require('express');
const app = express();

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
  • Kombinieren Sie clientseitige und serverseitige Validierung: Ein tiefgreifender Verteidigungsansatz erhöht die Sicherheit.

API-Tests (WSTG-APIT)

Die Sicherung von API-Endpunkten ist entscheidend, um Datenlecks und unbefugten Zugriff zu verhindern.

GraphQL Introspection Exposure

Wenn Sie die GraphQL-Selbstprüfung in der Produktion aktiviert lassen, wird Ihr API-Schema angezeigt.

Beispiel für anfälligen Code:

const express = require('express');
const app = express();

// Disable the X-Powered-By header
app.disable('x-powered-by');

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Schema-Offenlegung:Angreifer können Ihr API-Schema erkunden und so bei der Erstellung gezielter Angriffe helfen.

Abhilfe:

Deaktivieren Sie die Selbstbeobachtung in Produktionsumgebungen.

Verbesserter Code:

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet to secure headers
app.use(helmet());

// Your routes here

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Bedingte Selbstbeobachtung: Ermöglicht Selbstbeobachtung während der Entwicklung, deaktiviert sie jedoch in der Produktion.
  • Sicherheitsverbesserung: Reduziert die Angriffsfläche durch Ausblenden von Schemadetails.

Uneingeschränkte Abfragekomplexität

Tief verschachtelte oder komplexe Abfragen können Serverressourcen erschöpfen.

Beispiel für anfälligen Code:

// app.js
const express = require('express');
const app = express();

// Error handling middleware
app.use((err, req, res, next) => {
  res.status(500).send(err.stack); // Sends stack trace to the client
});

// Your routes here

app.listen(3000);

Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Problem:

  • Denial of Service (DoS): Komplexe Abfragen können zu einer hohen CPU- und Speicherauslastung führen.

Abhilfe:

Abfragetiefe und -komplexität begrenzen.

Verbesserter Code:

// app.js
const express = require('express');
const app = express();

// Your routes here

// Error handling middleware
if (app.get('env') === 'production') {
  // Production error handler
  app.use((err, req, res, next) => {
    // Log the error internally
    console.error(err);
    res.status(500).send('An unexpected error occurred.');
  });
} else {
  // Development error handler (with stack trace)
  app.use((err, req, res, next) => {
    res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}
`); }); } app.listen(3000);
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Erklärung:

  • Tiefenbegrenzung: Beschränkt die Tiefe von Abfragen, um eine Erschöpfung der Ressourcen zu verhindern.
  • Leistungsschutz: Stellt sicher, dass die API reaktionsfähig und verfügbar bleibt.

Abschluss

Das Sichern Ihrer Node.js-Anwendung erfordert einen mehrschichtigen Ansatz:

  • Verhindern Sie Informationslecks: Bereinigen Sie Code- und Serverkonfigurationen, um die Offenlegung vertraulicher Daten zu vermeiden.
  • Konfigurationen sicher verwalten:Standardanmeldeinformationen entfernen und Konfigurationsdateien sichern.
  • Eingaben validieren und bereinigen:Vertrauen Sie niemals Benutzereingaben.
  • Implementieren Sie die ordnungsgemäße Authentifizierung und Autorisierung:Stellen Sie sicher, dass Benutzer über den entsprechenden Zugriff verfügen.
  • Verwenden Sie starke Kryptographie:Schützen Sie Daten mit sicheren Algorithmen und Schlüsselverwaltung.
  • Gehen Sie ordnungsgemäß mit Fehlern um:Vermeiden Sie die Preisgabe vertraulicher Informationen.
  • Clientseitige Interaktionen schützen: XSS und andere browserbasierte Angriffe abschwächen.
  • Sichere APIs:Kontrollieren Sie die Offenlegung von Daten und setzen Sie eine Ratenbegrenzung durch.

Durch die Integration dieser Praktiken erhöhen Sie die Sicherheit Ihrer Anwendung, schützen Benutzerdaten und wahren das Vertrauen.


Weiterführende Literatur

  • OWASP Web Security Testing Guide (WSTG): OWASP WSTG
  • Node.js-Sicherheitsleitfaden: Node.js-Sicherheit
  • Express.js-Sicherheitstipps: Best Practices für die Express-Sicherheit
  • Best Practices für die GraphQL-Sicherheit: Apollo GraphQL-Sicherheit
  • OWASP Top Ten:OWASP Top Ten
  • MDN-Webdokumente – Web-Sicherheit:MDN-Web-Sicherheit

Hinweis: Dieser Leitfaden enthält allgemeine Empfehlungen. Bei besonderen Sicherheitsbedenken wenden Sie sich an einen Fachmann.

Das obige ist der detaillierte Inhalt vonSichern Ihrer Node.js-Anwendung: Ein umfassender Leitfaden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage