Fix: potential token time attack

This commit is contained in:
Dreamacro 2023-05-06 14:51:28 +08:00
parent 257fcef0b8
commit 4c3c64a34a
1 changed files with 10 additions and 2 deletions

View File

@ -2,11 +2,13 @@ package route
import (
"bytes"
"crypto/subtle"
"encoding/json"
"net"
"net/http"
"strings"
"time"
"unsafe"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
@ -96,6 +98,12 @@ func Start(addr string, secret string) {
}
}
func safeEuqal(a, b string) bool {
aBuf := unsafe.Slice(unsafe.StringData(a), len(a))
bBuf := unsafe.Slice(unsafe.StringData(b), len(b))
return subtle.ConstantTimeCompare(aBuf, bBuf) == 1
}
func authentication(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if serverSecret == "" {
@ -106,7 +114,7 @@ func authentication(next http.Handler) http.Handler {
// Browser websocket not support custom header
if websocket.IsWebSocketUpgrade(r) && r.URL.Query().Get("token") != "" {
token := r.URL.Query().Get("token")
if token != serverSecret {
if !safeEuqal(token, serverSecret) {
render.Status(r, http.StatusUnauthorized)
render.JSON(w, r, ErrUnauthorized)
return
@ -119,7 +127,7 @@ func authentication(next http.Handler) http.Handler {
bearer, token, found := strings.Cut(header, " ")
hasInvalidHeader := bearer != "Bearer"
hasInvalidSecret := !found || token != serverSecret
hasInvalidSecret := !found || !safeEuqal(token, serverSecret)
if hasInvalidHeader || hasInvalidSecret {
render.Status(r, http.StatusUnauthorized)
render.JSON(w, r, ErrUnauthorized)