Sicherheit & Robustheit härten

- SQLite-DSN: busy_timeout(5000) + WAL + foreign_keys gegen SQLITE_BUSY
- uid ist nie 0 mehr (0 = Sentinel für gelöscht/anonym), Retry bei Kollision
- scanEntries gibt Scan-Fehler zurück statt Zeilen still zu überspringen
- Session-timeout serverseitig auf 30 Tage gedeckelt (clientgesteuert)
- Bild-Upload: Dimensionen vor Decode prüfen (Decompression-Bomb-Schutz)
- Secure-Cookie via TLS-Erkennung (r.TLS / X-Forwarded-Proto)
- Rate-Limit (httprate, 20/min/IP) auf Login & Registrierung
- Vote nur auf existierende Beiträge (keine Waisen-Votes)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 17:07:17 +02:00
parent 5478e92253
commit 1313e9613c
7 changed files with 95 additions and 20 deletions
+9 -2
View File
@@ -4,9 +4,11 @@ import (
"encoding/json"
"log"
"net/http"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httprate"
)
func main() {
@@ -28,9 +30,14 @@ func routes() http.Handler {
r.Use(middleware.Recoverer)
// --- Auth (öffentlich) ---
r.Post("/auth/login", handleLogin)
// Login und Registrierung pro IP drosseln (Brute-Force-Bremse). bcrypt bremst
// zusätzlich, aber das Limit kappt automatisiertes Durchprobieren früh.
r.Group(func(r chi.Router) {
r.Use(httprate.LimitByIP(20, time.Minute))
r.Post("/auth/login", handleLogin)
r.Post("/auth/newuser", handleNewUser)
})
r.Get("/auth/logout", handleLogout)
r.Post("/auth/newuser", handleNewUser)
r.Get("/auth/sessioninfo", handleSessionInfo)
r.Get("/auth/headerbar", handleHeaderbar)