Initial commit: IHK Ausbildung materials
This commit is contained in:
257
1-Ausbildungsjahr/LF6-Webanwendungen/LF6-04-Sicherheit-Web.md
Normal file
257
1-Ausbildungsjahr/LF6-Webanwendungen/LF6-04-Sicherheit-Web.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# 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.
|
||||
|
||||
```sql
|
||||
-- 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**
|
||||
|
||||
```javascript
|
||||
// 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.
|
||||
|
||||
```html
|
||||
<!-- Gefährlich: Benutzereingabe direkt ausgeben -->
|
||||
<div>{{ benutzereingabe }}</div>
|
||||
<!-- Bei eingabe = <script>alert('XSS')</script> -->
|
||||
```
|
||||
|
||||
**Schutz: Output Encoding**
|
||||
|
||||
```javascript
|
||||
// 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)
|
||||
|
||||
```http
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```http
|
||||
# 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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
```javascript
|
||||
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
|
||||
|
||||
- [[LF6-03-Backend|Zurück: Backend-Entwicklung]]
|
||||
- [[LF4-IT-Sicherheit|IT-Sicherheit allgemein]]
|
||||
- [[LF3-05-Datenbankmanagement|Datenbank: SQL Injection]]
|
||||
|
||||
---
|
||||
|
||||
*Stand: 2024*
|
||||
Reference in New Issue
Block a user