fix(middleware): decode URL before suspicious SQL/XSS probes
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user