Cross-Site Request Forgery (CSRF)
Beschreibung
Cross-Site Request Forgery (CSRF) ist eine Schwachstelle, die auftritt, wenn eine Webanwendung nicht ausreichend verifiziert, ob eine Anfrage von einem autorisierten Benutzer stammt oder von einem Angreifer gefälscht wurde. CSRF-Angriffe bringen authentifizierte Benutzer dazu, unbeabsichtigte Aktionen auszuführen, indem sie das Vertrauen ausnutzen, das eine Webanwendung dem Browser des Benutzers entgegenbringt. Wenn ein Opfer eine bösartige Seite besucht oder auf einen präparierten Link klickt, während es bei einer Zielseite authentifiziert ist, sendet der Browser automatisch Session-Cookies mit, was dazu führt, dass der Server die Anfrage des Angreifers verarbeitet, als wäre sie legitim.
Risiko
CSRF-Angriffe können je nach angegriffener Funktionalität schwerwiegende Konsequenzen haben. Angreifer können Benutzer zwingen, Kontoeinstellungen zu ändern, Einkäufe zu tätigen, Geld zu überweisen, Daten zu modifizieren oder jede Aktion auszuführen, zu der das Opfer autorisiert ist. Der Samy-Wurm auf MySpace demonstrierte das virale Potenzial von CSRF kombiniert mit XSS und verbreitete sich in Stunden über Millionen von Profilen. Administrative CSRF-Angriffe können ganze Anwendungen kompromittieren, indem sie Administratoren zwingen, angreifer-kontrollierte Konten zu erstellen oder Sicherheitseinstellungen zu ändern. Die Schwachstelle ist besonders gefährlich, weil der Browser des Opfers automatisch alle notwendige Authentifizierung bereitstellt.
Lösung
Implementieren Sie Anti-CSRF-Tokens (Synchronizer-Tokens) in Formularen und AJAX-Anfragen. Tokens sollten pro Session eindeutig sein und serverseitig vor der Verarbeitung von Anfragen validiert werden. Verwenden Sie das SameSite-Cookie-Attribut, um zu verhindern, dass Cookies mit Cross-Site-Anfragen gesendet werden. Verifizieren Sie die Origin- und Referer-Header für zustandsändernde Operationen. Erfordern Sie Re-Authentifizierung für kritische Aktionen. Erwägen Sie die Implementierung benutzerdefinierter Request-Header für AJAX-Anfragen. Wenden Sie Defense in Depth mit mehreren Gegenmaßnahmen an.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Integrität | Umfang: Unbefugte Aktionen Angreifer führen Aktionen als der authentifizierte Benutzer aus, einschließlich Datenänderung, Käufe und Kontoänderungen. |
| Zugriffskontrolle | Umfang: Kontokompromittierung Passwortänderungen, E-Mail-Updates oder Änderungen an Sicherheitsfragen ermöglichen Kontoübernahme. |
| Vertraulichkeit | Umfang: Datenexfiltration CSRF kombiniert mit anderen Schwachstellen kann Benutzerdaten offenlegen oder übertragen. |
Beispielcode + Korrigierter Code
Anfälliger Code
<!-- ANFÄLLIG: Formular ohne CSRF-Schutz -->
<form action="/transfer" method="POST">
<input name="to_account" value="">
<input name="amount" value="">
<button type="submit">Überweisen</button>
</form>
<!-- Seite des Angreifers -->
<html>
<body>
<!-- Auto-übermittelndes verstecktes Formular -->
<form id="csrf" action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to_account" value="angreifer">
<input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf').submit();</script>
</body>
</html>
# ANFÄLLIG: Keine CSRF-Validierung
@app.route('/change-password', methods=['POST'])
def change_password():
# Keine CSRF-Token-Prüfung - Angreifer kann diese Anfrage fälschen
new_password = request.form['new_password']
user = get_current_user()
user.set_password(new_password)
return 'Passwort geändert'
@app.route('/delete-account', methods=['POST'])
def delete_account():
# Kein CSRF-Schutz bei kritischer Aktion!
user = get_current_user()
user.delete()
return 'Konto gelöscht'
Korrigierter Code
<!-- SICHER: Formular mit CSRF-Token -->
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input name="to_account" value="">
<input name="amount" value="">
<button type="submit">Überweisen</button>
</form>
from flask import Flask, session, request, abort
from flask_wtf.csrf import CSRFProtect
import secrets
app = Flask(__name__)
app.secret_key = secrets.token_hex(32)
csrf = CSRFProtect(app) # CSRF-Schutz global aktivieren
# SICHER: CSRF-Token wird automatisch von Flask-WTF validiert
@app.route('/change-password', methods=['POST'])
@csrf.protect # Validiert CSRF-Token
def change_password():
new_password = request.form['new_password']
user = get_current_user()
user.set_password(new_password)
return 'Passwort geändert'
# Manuelle CSRF-Validierung Beispiel
def validate_csrf_token(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.form.get('csrf_token')
if not token or token != session.get('csrf_token'):
abort(403, 'CSRF-Validierung fehlgeschlagen')
return f(*args, **kwargs)
return decorated
@app.before_request
def generate_csrf_token():
if 'csrf_token' not in session:
session['csrf_token'] = secrets.token_hex(32)
# SICHER: Zusätzlicher Schutz
@app.route('/delete-account', methods=['POST'])
@csrf.protect
def delete_account():
# Re-Authentifizierung für kritische Aktionen erfordern
password = request.form.get('confirm_password')
user = get_current_user()
if not user.verify_password(password):
abort(403, 'Passwortbestätigung erforderlich')
user.delete()
return 'Konto gelöscht'
// SICHER: AJAX mit CSRF-Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('/api/update-profile', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken // Benutzerdefinierter Header für AJAX
},
body: JSON.stringify(data),
credentials: 'same-origin' // Cookies einschließen
});
# SameSite-Cookie-Attribut setzen
@app.after_request
def set_cookie_flags(response):
# SameSite=Strict verhindert Cookies bei Cross-Site-Anfragen
# SameSite=Lax erlaubt GET-Navigation, blockiert aber POST
response.set_cookie('session', value=session_id,
samesite='Strict', secure=True, httponly=True)
return response
Ausgenutzt in der Praxis
Samy-Wurm (MySpace, 2005)
Der Samy-Wurm kombinierte XSS und CSRF, um sich über MySpace zu verbreiten, den Angreifer als Freund hinzuzufügen und bösartigen Code in Opferprofile einzufügen. Er infizierte über eine Million Benutzer innerhalb von 24 Stunden und demonstrierte das verheerende Potenzial von CSRF-Schwachstellen.
uTorrent Remote Code Execution (uTorrent, 2008)
Eine CSRF-Schwachstelle in uTorrents Weboberfläche ermöglichte Angreifern, Downloads bösartiger Torrents zu erzwingen, wenn Opfer angreifer-kontrollierte Websites besuchten, während uTorrent lief.
ERPNext Kontoübernahme (ERPNext, 2025)
CVE-2025 in ERPNext 14.82.1 ermöglicht Kontoübernahme durch CSRF und betrifft Enterprise-Resource-Planning-Systeme.
Tools zum Testen/Ausnutzen
-
Burp Suite — CSRF-PoC-Generator und Testfunktionen.
-
OWASP ZAP — Automatisierte CSRF-Schwachstellenerkennung.
-
CSRFTester — OWASP-Tool für CSRF-Tests.
CVE-Beispiele
-
CVE-2019-18897 — CSRF in Salt ermöglicht Root-Befehlsausführung.
-
CVE-2022-1388 — F5 BIG-IP Authentifizierungs-Bypass bezogen auf CSRF.
-
CVE-2024-27198 — JetBrains TeamCity Authentifizierungs-Bypass.
Referenzen
-
MITRE. "CWE-352: Cross-Site Request Forgery (CSRF)." https://cwe.mitre.org/data/definitions/352.html
-
OWASP. "Cross-Site Request Forgery Prevention Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html