
Websicherheit: Webanwendungen vor XSS, CSRF und Co. schützen
Die wichtigsten Grundlagen der Websicherheit: XSS, CSRF und SQL-Injection verhindern, Content Security Policy, Security-Header und sichere Abhängigkeiten.
Kurz gefasst: Die meisten erfolgreichen Angriffe auf Webanwendungen nutzen bekannte Lücken: eingeschleuster Code (XSS), gefälschte Anfragen (CSRF), SQL-Injection, fehlerhafte Zugriffskontrolle und veraltete Abhängigkeiten. Dagegen helfen bewährte Maßnahmen: Ausgaben konsequent escapen, parametrisierte Datenbankabfragen, SameSite-Cookies und CSRF-Tokens, eine Content Security Policy, Berechtigungsprüfung auf dem Server und regelmäßige Updates. Websicherheit ist damit vor allem eine Frage sauberer Gewohnheiten im Entwicklungsalltag.
Warum Grundlagen wichtiger sind als exotische Angriffe
Die OWASP Top 10, eine weit verbreitete Liste der häufigsten Risiken für Webanwendungen, zeigt seit Jahren ein ähnliches Bild: Fehlerhafte Zugriffskontrolle, Injection-Lücken und Fehlkonfigurationen stehen weit oben. Raffinierte Zero-Day-Angriffe sind dabei die Ausnahme. Die meisten dieser Fehler lassen sich mit Disziplin vermeiden.
Für ein KMU heißt das: Sie brauchen kein eigenes Security-Team, um die meisten Risiken auszuschließen. Sie brauchen eine Entwicklung, die diese Grundlagen von Anfang an mitdenkt.
Cross-Site Scripting (XSS)
Bei XSS gelingt es einem Angreifer, eigenes JavaScript in Ihre Seite einzuschleusen, etwa über ein Kommentarfeld oder einen manipulierten Link. Das Skript läuft dann im Browser anderer Nutzer und kann Sitzungsdaten stehlen oder Aktionen in deren Namen ausführen.
Ausgaben escapen
Frameworks wie React escapen Inhalte standardmäßig, wenn sie in JSX ausgegeben werden. Gefährlich wird es bei Ausnahmen: dangerouslySetInnerHTML, direktes Setzen von innerHTML oder Links mit javascript:-URLs aus Nutzereingaben. Wenn HTML aus Nutzereingaben wirklich nötig ist, etwa in einem Editor, muss es mit einer Bibliothek wie DOMPurify bereinigt werden.
Content Security Policy
Eine Content Security Policy (CSP) ist ein HTTP-Header, der festlegt, von wo Skripte, Styles und andere Ressourcen geladen werden dürfen. Eine strenge CSP mit Nonces oder Hashes verhindert, dass eingeschleuste Inline-Skripte ausgeführt werden, selbst wenn eine XSS-Lücke existiert. Sie ist damit eine wichtige zweite Verteidigungslinie.
Cross-Site Request Forgery (CSRF)
Bei CSRF bringt eine fremde Website den Browser eines angemeldeten Nutzers dazu, eine Anfrage an Ihre Anwendung zu senden, etwa eine Überweisung oder Passwortänderung. Der Browser schickt die Sitzungs-Cookies automatisch mit.
Moderne Browser setzen Cookies standardmäßig auf SameSite=Lax, was viele CSRF-Angriffe bereits verhindert. Verlassen Sie sich nicht allein darauf: Setzen Sie SameSite ausdrücklich, verwenden Sie für zustandsändernde Aktionen nie GET-Anfragen und ergänzen Sie bei Formularen CSRF-Tokens. Viele Frameworks bringen diesen Schutz bereits mit; Server Actions in Next.js prüfen zum Beispiel die Herkunft der Anfrage.
SQL-Injection und andere Injection-Angriffe
SQL-Injection entsteht, wenn Nutzereingaben direkt in eine Datenbankabfrage eingebaut werden. Ein Angreifer kann dann eigene SQL-Befehle ausführen und Daten auslesen oder löschen.
Die Lösung ist seit Langem bekannt: parametrisierte Abfragen (Prepared Statements). ORMs und Query-Builder wie Prisma, Drizzle oder Knex nutzen sie standardmäßig. Vorsicht ist bei Rohabfragen geboten, die per String-Verkettung gebaut werden. Dasselbe Prinzip gilt für andere Injection-Arten, etwa Befehle an das Betriebssystem oder NoSQL-Abfragen: Eingaben niemals ungeprüft in ausführbare Befehle übernehmen.
Zugriffskontrolle, Authentifizierung und Konfiguration
Berechtigungen auf dem Server prüfen
Ein häufiger Fehler: Die Oberfläche blendet Schaltflächen aus, die API prüft aber nicht, ob der Nutzer die Aktion ausführen darf. Wer die Anfrage manuell schickt, kommt durch. Prüfen Sie jede Anfrage auf dem Server, auch die Zugehörigkeit von Objekten: Darf dieser Nutzer genau diese Rechnung sehen? Wie Sie Anmeldung und Sitzungen sauber umsetzen, beschreibt unser Artikel zu OAuth, JWT und Sessions, und Hinweise zum Schnittstellendesign finden Sie unter API-Design für Webanwendungen.
Security-Header und HTTPS
Neben der CSP gehören einige Header zur Grundausstattung: Strict-Transport-Security erzwingt HTTPS, X-Content-Type-Options: nosniff verhindert falsch interpretierte Dateien, und frame-ancestors in der CSP schützt vor Clickjacking. Cookies mit Sitzungsdaten sollten HttpOnly und Secure gesetzt haben.
Abhängigkeiten und Geheimnisse
Moderne Anwendungen bestehen zu einem großen Teil aus fremden Paketen. Werkzeuge wie npm audit, Dependabot oder Renovate melden bekannte Schwachstellen und halten Abhängigkeiten aktuell. API-Schlüssel und Passwörter gehören in Umgebungsvariablen oder einen Secret-Manager, nie ins Repository.
Sicherheit und Datenschutz hängen eng zusammen. Welche Pflichten die DSGVO an die Entwicklung stellt, lesen Sie in unserem Leitfaden zur DSGVO-konformen Softwareentwicklung.
Häufige Fragen (FAQ)
Ist meine Anwendung sicher, weil sie React verwendet?
React schützt gut vor den häufigsten XSS-Fehlern, weil Ausgaben automatisch escaped werden. Gegen CSRF, SQL-Injection oder fehlende Berechtigungsprüfungen im Backend hilft es nicht. Sicherheit entsteht im Zusammenspiel von Frontend, Backend und Infrastruktur.
Brauche ich einen Penetrationstest?
Für Anwendungen mit sensiblen Daten, Zahlungen oder vielen Nutzern ist ein externer Penetrationstest sinnvoll, idealerweise vor dem Start und nach größeren Änderungen. Er prüft die sicheren Grundlagen in der Entwicklung, ersetzen kann er sie nicht.
Wie oft sollten Abhängigkeiten aktualisiert werden?
Laufend. Automatisierte Werkzeuge wie Dependabot oder Renovate schlagen Updates vor, und kritische Sicherheitsupdates sollten innerhalb weniger Tage eingespielt werden. Wer Updates monatelang aufschiebt, hat später ein deutlich schwierigeres Upgrade.
Reicht eine Web Application Firewall?
Eine WAF fängt bekannte Angriffsmuster ab und ist eine sinnvolle Ergänzung. Sie kennt aber die Logik Ihrer Anwendung nicht und kann etwa fehlende Berechtigungsprüfungen nicht erkennen. Sie ist eine zusätzliche Schicht, kein Ersatz für sicheren Code.
Fazit
Die meisten Sicherheitslücken in Webanwendungen sind bekannt und vermeidbar. Wer Ausgaben escaped, Abfragen parametrisiert, Berechtigungen auf dem Server prüft und Abhängigkeiten aktuell hält, schließt den Großteil der realen Angriffswege, lange bevor ein Penetrationstest nötig wird.
Wenn Sie eine Webanwendung mit hohen Sicherheitsanforderungen planen oder eine bestehende prüfen lassen möchten, sprechen Sie mit uns über Webentwicklung.
Ähnliche Beiträge
- React vs. Vue vs. Svelte: Frontend-Frameworks im Vergleich
React, Vue oder Svelte für Ihr nächstes Webprojekt? Ein sachlicher Vergleich von Konzept, Ökosystem, Performance, Fachkräften und Wartbarkeit.
- Warum Next.js unser Standard-Framework für Webentwicklung ist
Warum wir Webanwendungen standardmäßig mit Next.js bauen: Rendering, SEO, TypeScript, Self-Hosting in Deutschland und wann wir etwas anderes wählen.
- React-Anwendungen testen: Unit-, Integrations- und E2E-Tests
Wie Sie React-Anwendungen sinnvoll testen: Welche Tests sich lohnen, welche Werkzeuge passen und wie eine Teststrategie Fehler früh abfängt statt Zeit zu kosten.
- Clean Code in TypeScript: Prinzipien für wartbare Projekte
Praktische Clean-Code-Regeln für TypeScript: strikte Typen, sprechende Namen, kleine Funktionen und geprüfte Grenzen, mit Beispielen und typischen Fehlern.