Sicherheit von JavaScript-Anwendungen: Top-10-Schwachstellen für Anfänger
Die Sicherheit von Webanwendungen ist eines der wichtigsten Themen für jeden Entwickler. JavaScript (insbesondere auf der Serverseite Node.js) wird aufgrund seiner Beliebtheit oft zum Ziel von Angreifern. In diesem Artikel analysieren wir die 10 häufigsten Schwachstellen, auf die Anfänger stoßen, und zeigen, wie man sie vermeidet.
1. XSS (Cross-Site-Scripting)
XSS ist einer der häufigsten Angriffe, bei dem ein Angreifer ein bösartiges Skript in eine Webseite einschleust. Dies geschieht, wenn Benutzerdaten ohne Escape in HTML eingefügt werden.
Gefährlicher Code (anfällig):
app.get('/search', (req, res) => { const query = req.query.q; res.send(`<h1>Suchergebnisse: ${query}</h1>`);});Sicherer Code (Schutz):
const escapeHtml = require('escape-html');
app.get('/search', (req, res) => { const query = escapeHtml(req.query.q); res.send(`<h1>Suchergebnisse: ${query}</h1>`);});2. SQL-Injection
Wenn Sie SQL-Datenbanken (z. B. SQLite oder PostgreSQL) verwenden, können nicht escapede Abfragen zu Datenlecks führen.
Gefährlicher Code:
const user = req.body.username;db.query(`SELECT * FROM users WHERE name = '${user}'`);Sicherer Code (parametrisierte Abfragen verwenden):
const user = req.body.username;db.query('SELECT * FROM users WHERE name = $1', [user]);3. Unsichere Deserialisierung
Die Verwendung von JSON.parse() mit ungeprüften Daten kann zu Angriffen wie "prototype pollution" führen.
Beispiel einer Schwachstelle:
const data = JSON.parse(req.body.jsonData);// Wenn data __proto__ enthält, kann dies den Object-Prototyp ändernSchutz: Validieren Sie die Daten immer vor dem Parsen oder verwenden Sie Bibliotheken wie fast-json-stable-stringify.
4. Fehlende Eingabevalidierung (Input Validation)
Vertrauen Sie niemals Benutzerdaten. Überprüfen Sie immer Typ, Länge und Format der Daten.
// Schlecht: Alles akzeptierenapp.post('/profile', (req, res) => { const { name, age } = req.body; // ...});
// Gut: Validierenconst schema = { name: 'string', age: 'number' };if (typeof req.body.name !== 'string') throw new Error('Invalid name');5. CSRF (Cross-Site Request Forgery)
Ein Angriff, bei dem ein Angreifer einen Benutzer dazu zwingt, eine unerwünschte Aktion auf einer Website auszuführen, auf der er angemeldet ist.
Schutz: Verwenden Sie CSRF-Token.
const csrf = require('csurf');app.use(csrf({ cookie: true }));
app.get('/form', (req, res) => { res.render('form', { csrfToken: req.csrfToken() });});6. Informationsleck durch Fehler
Zeigen Sie dem Benutzer niemals detaillierte Fehlermeldungen an – dies gibt Hackern Informationen über die Struktur Ihrer Anwendung.
Schlecht:
app.use((err, req, res, next) => { res.status(500).send(err.stack); // Aufrufstapel-Leck!});Gut:
app.use((err, req, res, next) => { console.error(err.stack); // Für uns selbst protokollieren res.status(500).send('Interner Serverfehler');});7. Unsichere Verwendung von eval() und Function()
Die Funktionen eval() und new Function() führen einen String als Code aus – dies ist extrem gefährlich, wenn der String Benutzerdaten enthält.
// Gefährlich! Tun Sie das niemalsconst userInput = req.body.code;eval(userInput); // Ein Angreifer kann jeden Code ausführenAlternative: