Sicherheits-Basics für Webprojekte: Die 15 Dinge, die du nie auslassen solltest

Sicherheits-Basics für Webprojekte

Du musst kein Security-Ninja sein. Aber wenn du diese 15 Basics sauber machst, sparst du dir 80% der typischen Hacks, Datenpannen und „Warum ist die Seite jetzt Crypto-Miner?“-Momente.

Websecurity klingt oft nach „Enterprise-Kram“. In echt sind die meisten Vorfälle brutal simpel: veraltete Plugins, schwache Admin-Logins, fehlende Updates, offenes Upload-Verzeichnis, Logs, die keiner anschaut.

Das hier ist dein pragmatischer Sicherheits-Gürtel. Nicht perfekt. Aber solide. Und vor allem: umsetzbar, ohne alles neu zu bauen.

Wichtig: Das ist keine Rechtsberatung und kein vollständiger Penetrationstest. Das ist eine Checkliste, die du bei jedem Projekt abhaken solltest – egal ob CMS, Custom App, API oder „Landingpage mit Formular“.

Warum diese Basics so viel bringen

OWASP beschreibt seit Jahren die gleichen Hauptprobleme: kaputte Zugriffskontrollen, Injection, XSS, unsichere Konfigurationen, veraltete Komponenten, fehlendes Logging. Das sind keine „Edge Cases“, das ist Alltag. Wenn du die Basics sauber machst, schneidest du ganze Klassen von Angriffen ab.

Die 15 Dinge, die du nie auslassen solltest

1) HTTPS überall + HSTS (keine Ausreden)

HTTPS ist nicht optional. Ohne TLS sind Logins, Sessions und Formulardaten ein Freifahrtschein. Setze HSTS, damit Browser nicht versehentlich auf HTTP zurückfallen.

  • Quick Win: Redirect HTTP → HTTPS, HSTS sauber konfigurieren (vorsichtig mit Preload).
  • Typischer Fail: Mixed Content (Bilder/Skripte noch per HTTP) → fixen.

2) Secure Cookies: Secure, HttpOnly, SameSite

Sessions gehören in Cookies, die nicht aus JS lesbar sind und nicht „nebenbei“ cross-site mitfliegen.

  • Quick Win: Session-Cookie: Secure + HttpOnly + SameSite (meist Lax als Startpunkt).
  • Typischer Fail: Session-Cookie ohne Secure auf HTTPS-Seite.

3) Security Headers als Grundhygiene

Header sind kein Allheilmittel, aber extrem günstige Risikoreduktion.

  • Minimum: Content-Security-Policy (CSP), X-Content-Type-Options, Referrer-Policy.
  • Optional/je nach Bedarf: Permissions-Policy.
  • Quick Win: Starte CSP in „Report-Only“, dann schärfen.

4) CSP (Content Security Policy): XSS-Rettungsring

CSP ist der beste Hebel gegen XSS-Schäden, wenn sie doch irgendwo reinkommen. Aber: CSP „mal eben“ ist oft kaputt, weil Drittanbieter-Skripte wild sind.

  • Quick Win: CSP Report-Only einschalten, Reports auswerten, dann schrittweise restriktiver werden.
  • No-Go: unsafe-inline als Dauerlösung „weil sonst geht’s nicht“.

5) Login-Härtung: MFA, Rate Limits, Lockouts

Brute Force ist billig. MFA ist billig. Rate Limiting ist billig. Du willst die billigen Sachen nutzen.

  • Quick Win: MFA für Admins/Redakteure, Rate Limit auf Login/Reset, sinnvolle Sperren nach Fehlversuchen.
  • Typischer Fail: Admin-Login öffentlich ohne Rate Limit + „admin/admin“ in Varianten.

6) Passwort-Speicherung richtig: nie plaintext, nie „eigener Hash“

Passwörter werden gehasht und gesalzen. Punkt. Nimm etablierte Algorithmen (Argon2 oder bcrypt) über Framework/Libs, nicht „DIY Crypto“.

  • Quick Win: Prüfen, ob dein Stack Argon2/bcrypt nutzt und die Parameter zeitgemäß sind.
  • Typischer Fail: SHA-256 „weil ist doch Hash“ (ist für Passwörter nicht die Idee).

7) Zugriffskontrolle: Least Privilege überall

Die häufigsten Schäden entstehen, wenn ein Account „zu viel darf“. Admin-Accounts, DB-User, API-Keys, S3-Buckets – alles minimal.

  • Quick Win: DB-User pro App, keine globalen Root-Rechte; Admin-Rollen nur für wenige.
  • Typischer Fail: Ein Key/Account für alles, überall im Code verteilt.

8) CSRF-Schutz für state-changing Requests

Wenn ein eingeloggter User durch eine fremde Seite Aktionen auslösen kann (Form submit, API POST), hast du ein Problem.

  • Quick Win: CSRF Tokens für Formulare + same-site Cookies; bei APIs: echte Auth (Tokens) + CORS sauber.
  • Typischer Fail: Admin-Aktionen per GET oder ohne Token.

9) XSS vermeiden: Output-Encoding + saubere Templates

XSS kommt oft durch „kleine“ Stellen: Kommentare, Suchfelder, UGC, WYSIWYG, Parameter, die irgendwo ungefiltert gerendert werden.

  • Quick Win: Standard: Output escapen, HTML nur whitelisten (sanitizen), nie blind innerHTML-Style.
  • Typischer Fail: „Wir filtern Input“ und rendern dann trotzdem unsicher.

10) File Uploads: der unterschätzte Endboss

Uploads sind ein Klassiker für RCE/Defacement. „Nur Bilder“ heißt nicht „sicher“.

  • Quick Win: Content-Type nicht vertrauen, echte Prüfung (Magic bytes), serverseitig umbenennen, außerhalb Webroot speichern.
  • Quick Win: Wenn du Bilder brauchst: re-encode (neu speichern), nicht original ausliefern.
  • Typischer Fail: Uploads direkt öffentlich ausführbar (z.B. .php im Upload-Ordner).

11) Secrets-Management: nichts Hartkodiertes, nichts im Repo

API-Keys, DB-Passwörter, JWT-Secrets – das gehört nicht in Git, nicht in Frontend-Bundles, nicht in „config.php“ im Webroot.

  • Quick Win: Secrets in Environment/Secret Store; Rotation planen.
  • Typischer Fail: Keys im JS oder in öffentlich zugänglichen Dateien.

12) Updates & Patch-Management: Prozess statt Hoffnung

Die Mehrheit der Kompromittierungen passiert über bekannte Lücken in alten Versionen. Nicht weil Angreifer genial sind, sondern weil Updates fehlen.

  • Quick Win: Monatlicher Patch-Tag + Security-Updates sofort (CMS, Plugins, Server, Libraries).
  • Typischer Fail: „Wir updaten nicht, sonst geht was kaputt.“ Dann geht irgendwann alles kaputt.

13) Dependency Hygiene: SBOM-light & automatische Checks

Du musst nicht gleich „Supply Chain Enterprise“ spielen. Aber: Dependencies sind Angriffsfläche. Automatische Scans sind low-effort.

  • Quick Win: Dependabot/Snyk/GitHub Security Alerts (oder Äquivalent) aktivieren.
  • Typischer Fail: „Wir pinnen nie Versionen“ oder „wir updaten nie“.

14) Logging & Monitoring: sonst merkst du’s zu spät

Wenn du keinen Alarm bekommst, ist „Security“ nur ein Gefühl. Du brauchst Logs, die du auswerten kannst: Login-Fails, ungewöhnliche Admin-Aktionen, 500er-Spikes, WAF-Events.

  • Quick Win: Login-Fails & Admin-Changes loggen, Alarme auf Anomalien (z.B. viele Fails in kurzer Zeit).
  • Typischer Fail: Logs existieren, aber niemand schaut rein.

15) Backups + Restore-Test (ohne Restore ist es kein Backup)

Ransomware/Defacement/Fehler passieren. Deine Superpower ist ein schneller Restore.

  • Quick Win: 3-2-1 Prinzip als Orientierung: mehrere Kopien, unterschiedliche Medien/Orte, eine offline/immutable.
  • Quick Win: Restore regelmäßig testen (sonst Überraschung im Ernstfall).
  • Typischer Fail: Backup läuft „grün“, aber Restore ist nie getestet.

Vergleichstabelle: Was bringt am meisten fürs Geld?

Maßnahme Schützt vor Aufwand Quick Win
HTTPS + HSTS MITM, Session Hijacking niedrig HTTP→HTTPS Redirect + HSTS
MFA + Rate Limiting Brute Force, Credential Stuffing niedrig–mittel MFA nur für Admins starten
CSP (Report-Only → enforcing) XSS-Folgeschäden mittel Report-Only aktivieren
Updates/Patches Known vulns mittel (Prozess) Fixer Patch-Tag + Alerts
Backups + Restore-Test Ransomware, Defacement, Fehler mittel Monatlicher Restore-Test
Uploads hardenen RCE, Malware, Defacement mittel–hoch Außerhalb Webroot speichern

So setzt du’s um: 2-Stunden-Security-Bootstrap

So setzt du’s um

  1. Transport & Sessions: HTTPS erzwingen, HSTS, Secure/HttpOnly/SameSite prüfen.
  2. Login: MFA für Admins an, Rate Limit / Lockout, Passwort-Policy checken.
  3. Headers: CSP Report-Only, Referrer-Policy, X-Content-Type-Options setzen.
  4. Input/Actions: CSRF Tokens für Forms, Output-Encoding prüfen, Upload-Regeln härten.
  5. Ops: Updates/Alerts aktivieren, Logs + Alarm für Login-Fails, Backup/Restore-Test terminieren.

Mini-Use-Case: „CMS-Seite mit Formular und Upload“

  • Formular: CSRF Token + serverseitige Validierung + Output-Escaping
  • Upload: Magic bytes check + re-encode + außerhalb Webroot speichern
  • Admin: MFA + Rate Limit + „/admin“ nicht als öffentliche Partyzone

Typische Fehler & wie du sie vermeidest

  • Fehler: CSP direkt „hart“ setzen und dann alles mit unsafe-inline retten. Fix: Report-Only starten, dann gezielt härten.
  • Fehler: „Notwendig“ als Ausrede für Tracking-Skripte. Fix: Security/Privacy sauber trennen, nur wirklich nötige Dinge ohne Extra-Checks.
  • Fehler: Admin-Accounts teilen („wir sind doch nur zu dritt“). Fix: eigene Accounts, least privilege, Logs pro Person.
  • Fehler: Uploads im Webroot + Dateiname bleibt wie hochgeladen. Fix: umbenennen, isolieren, prüfen, re-encode.
  • Fehler: Backups nie getestet. Fix: Restore-Test als Pflichttermin.

Fazit: Security ist kein Projekt, es ist eine Routine

Wenn du diese 15 Basics drauf hast, bist du nicht „unhackbar“. Aber du bist deutlich weniger attraktiv als das nächste Projekt mit Admin ohne MFA und Plugins von 2019.

Nächster Schritt: Mach heute die 2-Stunden-Runde (HTTPS/Cookies, Login, Headers, Updates/Alerts, Backup/Restore-Test). Und dann: Patch-Tag als fester Prozess. Security ohne Routine ist nur ein gutes Gefühl.

FAQ

Welche Security Header brauche ich wirklich als Minimum?

Als Start: CSP (erst Report-Only), X-Content-Type-Options, Referrer-Policy. Dazu HTTPS/HSTS. Dann je nach Projekt Permissions-Policy.

Ja, aber iterativ. Starte mit Report-Only, sammle Reports, räume Drittanbieter auf und zieh die Policy dann enger. CSP ist kein „ein Klick“, aber einer der besten XSS-Schadensbegrenzer.

Wenn dein Stack Argon2 sauber unterstützt: Argon2 ist modern und dafür gemacht. bcrypt ist ebenfalls etabliert und ok. Wichtig ist: nicht selbst bauen, Parameter nicht „zu schwach“ lassen, und niemals schnelle Hashes wie SHA-256 als Passwort-Hash missbrauchen.

Für Admin-/Editor-Logins: ja, wenn du kannst. Credential Stuffing trifft auch kleine Seiten. MFA ist eine der günstigsten Schutzmaßnahmen mit großer Wirkung.

Minimal-Setup: Dateityp serverseitig prüfen (nicht nur MIME), umbenennen, außerhalb Webroot speichern, optional re-encode (bei Bildern). Und niemals ausführbare Dateien im Upload-Ordner zulassen.

Keine Routine: Updates werden geschoben, Logs werden nicht überwacht, Backups werden nie getestet. Angriffe sind dann nicht „ob“, sondern „wann“ – und du merkst es zu spät.