P2.3: timing-safe сравнение admin bearer-токена
bearerAuthMiddleware теперь сравнивает Authorization через subtle.ConstantTimeCompare (с предварительной проверкой длины), а не через != — устраняет timing side-channel при подборе admin-токена.
This commit is contained in:
+6
-1
@@ -6,6 +6,7 @@ package admin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/subtle"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -119,8 +120,12 @@ func (h *Handler) RegisterPublicRoutes(r *mux.Router) {
|
|||||||
func (h *Handler) bearerAuthMiddleware(next http.Handler) http.Handler {
|
func (h *Handler) bearerAuthMiddleware(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
authHeader := r.Header.Get("Authorization")
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
// Timing-safe сравнение: длина префикса и сам токен проверяются отдельно,
|
||||||
|
// само сравнение значения — через subtle.ConstantTimeCompare, чтобы не
|
||||||
|
// давать timing side-channel при подборе admin-токена.
|
||||||
expected := "Bearer " + h.adminToken
|
expected := "Bearer " + h.adminToken
|
||||||
if authHeader != expected {
|
if len(authHeader) != len(expected) ||
|
||||||
|
subtle.ConstantTimeCompare([]byte(authHeader), []byte(expected)) != 1 {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"})
|
json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"})
|
||||||
|
|||||||
Reference in New Issue
Block a user