Sicherheit von JavaScript-Anwendungen: Die Top 10 Schwachstellen
JavaScript, insbesondere in der Node.js-Umgebung, ist zur Grundlage der modernen Webentwicklung geworden. Seine Beliebtheit macht Anwendungen jedoch zu einem attraktiven Ziel für Angriffe. Die Missachtung von Sicherheitsaspekten kann zu Datenlecks, finanziellen Verlusten und Reputationsschäden führen. In diesem Artikel analysieren wir die Top 10 der kritischsten Schwachstellen von JavaScript (Node.js)-Anwendungen, basierend auf dem OWASP Top 10 Standard, und zeigen anhand von Codebeispielen, wie man sie verhindern kann.
1. Injection
Injection-Angriffe bleiben eine der gefährlichsten Bedrohungen. Im Kontext von Node.js treten am häufigsten SQL-Injection und NoSQL-Injection (z. B. in MongoDB) auf.
Problem
Die direkte Verkettung von Benutzereingaben in Datenbankabfragen ermöglicht es einem Angreifer, beliebigen Code auszuführen.
Beispiel für anfälligen Code
const user = req.body.username;const query = `SELECT * FROM users WHERE username = '${user}'`;db.query(query, callback);Lösung
Verwenden Sie parametrisierte Abfragen oder ORM/ODM. Für MongoDB verwenden Sie mongo-sanitize.
const query = 'SELECT * FROM users WHERE username = $1';db.query(query, [user], callback);2. Fehlerhafte Authentifizierung und Session-Management
Schwache Authentifizierung ist ein direkter Weg zur Kompromittierung von Konten.
Problem
Verwendung vorhersagbarer Token (z. B. JWT mit dem Algorithmus none), Speicherung von Passwörtern im Klartext oder fehlende Begrenzung der Anmeldeversuche.
Beispiel für eine Schwachstelle
// JWT ohne Algorithmus-Überprüfungconst token = jwt.sign({ user: 'admin' }, 'secret', { algorithm: 'none' });Lösung
- Überprüfen Sie immer den JWT-Algorithmus:
jwt.verify(token, secret, { algorithms: ['HS256'] }). - Speichern Sie Passwörter mit
bcryptoderargon2. - Implementieren Sie eine Begrenzung der Anmeldeversuche (
express-rate-limit).
const bcrypt = require('bcrypt');const saltRounds = 10;const hash = await bcrypt.hash(password, saltRounds);3. XSS (Cross-Site Scripting)
XSS ermöglicht das Einschleusen eines bösartigen Skripts in eine Webseite, das dann im Browser des Opfers ausgeführt wird.
Problem
Ausgabe von Benutzerinhalten ohne Escape, insbesondere bei Verwendung von Server-Side Rendering (SSR) in Next.js oder Nuxt.js.
Anfälliger Code (Express)
res.send(`<h1>Hello, ${req.query.name}</h1>`);Lösung
- Escapen Sie die Ausgabe: Verwenden Sie Bibliotheken wie
escape-htmloder Template-Engines mit automatischem Escaping (EJS, Pug). - Setzen Sie den CSP-Header (Content Security Policy):
helmet.contentSecurityPolicy().
const helmet = require('helmet');app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"] }}));4. Unsichere direkte Objektreferenzen (IDOR)
Diese Schwachstelle tritt auf, wenn ein Benutzer auf Objekte (Dateien, Datenbankeinträge) zugreifen kann, indem er deren Identifikator kennt oder errät.
Beispiel
app.get('/api/user/:id', (req, res) => { // Keine Prüfung, ob req.user.id === req.params.id const user = db.findUser(req.params.id); res.json(user);});Lösung
Überprüfen Sie immer die Zugriffsrechte auf Serverebene.
if (req.user.id !== req.params.id) { return res.status(403).send('Forbidden');}5. Unsichere Sicherheitskonfiguration
Dies umfasst die Verwendung von Standard-Anmeldeinformationen, Debug-Modi in der Produktion sowie falsche CORS-Einstellungen.
Problem
// Offenes CORSapp.use(cors({ origin: '*' }));