mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
use constant time comparison (#3452)
This commit is contained in:
@@ -19,6 +19,9 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
)
|
||||
|
||||
type HTTPAuthWraper struct {
|
||||
@@ -46,8 +49,9 @@ func (aw *HTTPAuthWraper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type HTTPAuthMiddleware struct {
|
||||
user string
|
||||
passwd string
|
||||
user string
|
||||
passwd string
|
||||
authFailDelay time.Duration
|
||||
}
|
||||
|
||||
func NewHTTPAuthMiddleware(user, passwd string) *HTTPAuthMiddleware {
|
||||
@@ -57,32 +61,28 @@ func NewHTTPAuthMiddleware(user, passwd string) *HTTPAuthMiddleware {
|
||||
}
|
||||
}
|
||||
|
||||
func (authMid *HTTPAuthMiddleware) SetAuthFailDelay(delay time.Duration) *HTTPAuthMiddleware {
|
||||
authMid.authFailDelay = delay
|
||||
return authMid
|
||||
}
|
||||
|
||||
func (authMid *HTTPAuthMiddleware) Middleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
reqUser, reqPasswd, hasAuth := r.BasicAuth()
|
||||
if (authMid.user == "" && authMid.passwd == "") ||
|
||||
(hasAuth && reqUser == authMid.user && reqPasswd == authMid.passwd) {
|
||||
(hasAuth && util.ConstantTimeEqString(reqUser, authMid.user) &&
|
||||
util.ConstantTimeEqString(reqPasswd, authMid.passwd)) {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
if authMid.authFailDelay > 0 {
|
||||
time.Sleep(authMid.authFailDelay)
|
||||
}
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func HTTPBasicAuth(h http.HandlerFunc, user, passwd string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
reqUser, reqPasswd, hasAuth := r.BasicAuth()
|
||||
if (user == "" && passwd == "") ||
|
||||
(hasAuth && reqUser == user && reqPasswd == passwd) {
|
||||
h.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type HTTPGzipWraper struct {
|
||||
h http.Handler
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ package util
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
mathrand "math/rand"
|
||||
@@ -139,3 +140,7 @@ func RandomSleep(duration time.Duration, minRatio, maxRatio float64) time.Durati
|
||||
time.Sleep(d)
|
||||
return d
|
||||
}
|
||||
|
||||
func ConstantTimeEqString(a, b string) bool {
|
||||
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
|
||||
}
|
||||
|
Reference in New Issue
Block a user