fix: harden LDAP STS rate-limit source IP

Use the socket peer address for LDAP STS per-IP rate limiting instead of the generic forwarded-header-aware helper. This keeps the security-sensitive rate-limit key from trusting spoofable X-Forwarded-For, X-Real-IP, and Forwarded headers while leaving the rest of the source-IP behavior unchanged.

Add focused regression coverage for RemoteAddr parsing, header spoofing, and peer-address bucket selection.
This commit is contained in:
Feng Ruohang
2026-04-16 21:21:53 +08:00
parent 18b712d49a
commit 9e10f6d9a0
2 changed files with 172 additions and 2 deletions
+10 -2
View File
@@ -25,6 +25,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"strconv"
@@ -36,7 +37,6 @@ import (
"github.com/minio/minio/internal/auth"
idldap "github.com/minio/minio/internal/config/identity/ldap"
"github.com/minio/minio/internal/config/identity/openid"
"github.com/minio/minio/internal/handlers"
"github.com/minio/minio/internal/hash/sha256"
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
@@ -487,11 +487,19 @@ func (r *stsLDAPLoginKeyReservation) finalize(now time.Time, refund bool) {
r.finalized = true
}
func getSTSLDAPLoginSourceIP(r *http.Request) string {
sourceIP, _, err := net.SplitHostPort(r.RemoteAddr)
if err == nil {
return sourceIP
}
return r.RemoteAddr
}
// reserveSTSLDAPLogin acquires immediate tokens from the per-source and
// per-username limiters before contacting LDAP. Call Commit on auth failures
// and Cancel when the attempt should not count as an authentication failure.
func reserveSTSLDAPLogin(r *http.Request) *stsLDAPLoginReservation {
return globalSTSLDAPLoginRateLimiter.Reserve(handlers.GetSourceIPRaw(r), r.Form.Get(stsLDAPUsername))
return globalSTSLDAPLoginRateLimiter.Reserve(getSTSLDAPLoginSourceIP(r), r.Form.Get(stsLDAPUsername))
}
func ldapBindErrorToSTS(err error) (STSErrorCode, error) {