- LF9-03 Virtualisierung: Docker Compose + Volume examples - LF6-02 Frontend: To-Do list practical example - LF8-04 ETL: Complete ETL pipeline example - LF6-04 Sicherheit: Express.js security headers - LF2-04 Nutzwertanalyse: Cloud provider selection example - LF9-04 Monitoring: Prometheus alerts + Python logging
5.4 KiB
5.4 KiB
6.4 Web-Sicherheit
OWASP Top 10
Die wichtigsten Sicherheitsrisiken
OWASP Top 10 (2021)
├── A01: Broken Access Control
├── A02: Cryptographic Failures
├── A03: Injection
├── A04: Insecure Design
├── A05: Security Misconfiguration
├── A06: Vulnerable Components
├── A07: Authentification Failures
├── A08: Software and Data Integrity Failures
├── A09: Security Logging Failures
└── A10: Server-Side Request Forgery
Injection
SQL Injection
Problem: Benutzereingaben werden direkt in SQL-Abfragen eingebaut.
-- Gefährlich
SELECT * FROM benutzer WHERE name = '" + name + "'
-- Bei name = "' OR '1'='1"
SELECT * FROM benutzer WHERE name = '' OR '1'='1'
-- → Alle Benutzer werden zurückgegeben!
Schutz: Prepared Statements
// Gefährlich
db.query("SELECT * FROM users WHERE name = '" + name + "'");
// Sicher - Parameterized Query
db.query("SELECT * FROM users WHERE name = ?", [name]);
XSS (Cross-Site Scripting)
Problem: Schadcode wird in Webseiten eingeschleust.
<!-- Gefährlich: Benutzereingabe direkt ausgeben -->
<div>{{ benutzereingabe }}</div>
<!-- Bei eingabe = <script>alert('XSS')</script> -->
Schutz: Output Encoding
// HTML-Escaping
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// React macht das automatisch
<div>{benutzereingabe}</div>
Content Security Policy (CSP)
Content-Security-Policy: default-src 'self'; script-src 'self'
Praktisches Beispiel: Express.js Sicherheits-Header
const helmet = require('helmet');
const cors = require('cors');
app.use(helmet());
// CORS konfigurieren
app.use(cors({
origin: 'https://meine-app.de',
credentials: true
}));
// Rate Limiting
const rateLimit = require('express-rate-limit');
app.use('/api/', rateLimit({
windowMs: 15 * 60 * 1000, // 15 Minuten
max: 100, // Max 100 Anfragen
message: 'Zu viele Anfragen, bitte später versuchen'
}));
CSRF (Cross-Site Request Forgery)
Das Problem
CSRF-Angriff
1. Opfer ist eingeloggt bei bank.com
2. Opfer besucht bösartige Seite
3. Bösartige Seite sendet Request an bank.com
4. Browser sendet automatisch Session-Cookie
5. Überweisung wird ausgeführt
Schutz: CSRF-Token
// Server: Token generieren
app.get('/form', (req, res) => {
const csrfToken = crypto.randomBytes(32).toString('hex');
req.session.csrfToken = csrfToken;
res.render('form', { csrfToken });
});
// Server: Token prüfen
app.post('/transfer', (req, res) => {
if (req.body.csrfToken !== req.session.csrfToken) {
return res.status(403).send('CSRF-Angriff erkannt');
}
// Weiter mit Überweisung...
});
Authentifizierung
Unsichere Praktiken
Vermeiden
├── Passwörter im Klartext speichern
├── Schwache Passwörter erlauben
├── Keine Zwei-Faktor-Authentifizierung
├── Session-IDs in URL
└── Unbegrenzte Login-Versuche
Sichere Authentifizierung
// 1. Passwörter hashen
const hash = await bcrypt.hash(passwort, 12);
// 2. Rate Limiting
const rateLimit = require('express-rate-limit');
app.use('/login', rateLimit({
windowMs: 15 * 60 * 1000,
max: 5 // 5 Versuche
}));
// 3. Sichere Session
app.use(session({
secret: 'geheimer-schluessel',
httpOnly: true,
secure: true, // HTTPS
sameSite: 'strict'
}));
Sicherheits-Header
Wichtige Header
# HSTS - HTTPS erzwingen
Strict-Transport-Security: max-age=31536000; includeSubDomains
# X-Content-Type-Options
X-Content-Type-Options: nosniff
# X-Frame-Options - Clickjacking
X-Frame-Options: DENY
# Content Security Policy
Content-Security-Policy: default-src 'self'
# Referrer Policy
Referrer-Policy: strict-origin-when-cross-origin
Implementierung in Express
const helmet = require('helmet');
app.use(helmet());
Eingabevalidierung
Grundprinzip
Validierung - Regeln
├── Nie Benutzereingaben vertrauen
├── Client-seitige Validierung reicht nicht
├── Whitelist statt Blacklist
├── Länge und Format prüfen
└── Alle Eingaben validieren
Validierungsbeispiel
const Joi = require('joi');
const benutzerSchema = Joi.object({
name: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
email: Joi.string()
.email()
.required(),
alter: Joi.number()
.integer()
.min(18)
.max(150)
});
// Validierung
const { error, value } = benutzerSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details });
}
Checkliste Web-Sicherheit
Sicherheits-Checkliste
□ HTTPS erzwingen
□ Sicherheits-Header setzen
□ SQL Injection verhindern (Prepared Statements)
□ XSS verhindern (Escaping)
□ CSRF-Token verwenden
□ Passwörter hashen (bcrypt)
□ Rate Limiting
□ Eingaben validieren
□ Fehlermeldungen nicht zu detailliert
□ Regelmäßige Updates
□ Sicherheitstests durchführen
Querverweise
Stand: 2024