fix(middleware): decode URL before suspicious SQL/XSS probes

This commit is contained in:
2026-05-06 20:13:56 +02:00
parent 98985db537
commit 102f1d8400
+23 -4
View File
@@ -3,6 +3,7 @@ package middleware
import ( import (
"log" "log"
"net/http" "net/http"
"net/url"
"os" "os"
"strings" "strings"
"sync" "sync"
@@ -53,7 +54,10 @@ func SecurityLoggingMiddleware(logger *SecurityLogger) func(http.Handler) http.H
next.ServeHTTP(rw, r) next.ServeHTTP(rw, r)
userID := GetUserIDFromContext(r.Context()) userUID := uint(0)
if u := GetUserIDFromContext(r.Context()); u != nil {
userUID = *u
}
ip := getClientIP(r) ip := getClientIP(r)
event := SecurityEvent{ event := SecurityEvent{
@@ -61,7 +65,7 @@ func SecurityLoggingMiddleware(logger *SecurityLogger) func(http.Handler) http.H
UserAgent: r.UserAgent(), UserAgent: r.UserAgent(),
Path: r.URL.Path, Path: r.URL.Path,
Method: r.Method, Method: r.Method,
UserID: userID, UserID: userUID,
Timestamp: start, Timestamp: start,
} }
@@ -106,12 +110,15 @@ func SuspiciousActivityMiddleware(logger *SecurityLogger) func(http.Handler) htt
suspicious := false suspicious := false
details := "" details := ""
if containsSQLInjection(r.URL.RawQuery) || containsSQLInjection(r.URL.Path) { pathProbe := layeredUnescape(r.URL.Path, url.PathUnescape)
queryProbe := layeredUnescape(r.URL.RawQuery, url.QueryUnescape)
if containsSQLInjection(pathProbe) || containsSQLInjection(queryProbe) {
suspicious = true suspicious = true
details = "Potential SQL injection attempt" details = "Potential SQL injection attempt"
} }
if containsXSS(r.URL.RawQuery) || containsXSS(r.URL.Path) { if containsXSS(pathProbe) || containsXSS(queryProbe) {
suspicious = true suspicious = true
details = "Potential XSS attempt" details = "Potential XSS attempt"
} }
@@ -159,6 +166,18 @@ func getClientIP(r *http.Request) string {
return GetSecureClientIP(r) return GetSecureClientIP(r)
} }
func layeredUnescape(s string, decoder func(string) (string, error)) string {
out := s
for range 3 {
d, err := decoder(out)
if err != nil || d == out {
return out
}
out = d
}
return out
}
func containsSQLInjection(input string) bool { func containsSQLInjection(input string) bool {
sqlPatterns := []string{ sqlPatterns := []string{
"' OR '1'='1", "' OR '1'='1",