Просмотр исходного кода

security(metrics): use constant-time comparison for metrics endpoint credentials

The metrics Basic Auth check used != for username and password, which is
technically vulnerable to timing side-channel attacks. Since the metrics
credentials are typically short static config values, the timing difference is
very likely to be in the noise level, but oh well, it's a good practise to do
credential validation in constant time.
jvoisin 1 неделя назад
Родитель
Сommit
3747e686af
1 измененных файлов с 6 добавлено и 1 удалено
  1. 6 1
      internal/http/server/metrics.go

+ 6 - 1
internal/http/server/metrics.go

@@ -8,6 +8,7 @@ import (
 	"net/http"
 	"net/http"
 
 
 	"miniflux.app/v2/internal/config"
 	"miniflux.app/v2/internal/config"
+	"miniflux.app/v2/internal/crypto"
 	"miniflux.app/v2/internal/http/request"
 	"miniflux.app/v2/internal/http/request"
 
 
 	"github.com/prometheus/client_golang/prometheus/promhttp"
 	"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -54,7 +55,11 @@ func isAllowedToAccessMetricsEndpoint(r *http.Request) bool {
 			return false
 			return false
 		}
 		}
 
 
-		if username != config.Opts.MetricsUsername() || password != config.Opts.MetricsPassword() {
+		// Both checks have to be run to avoid leaking informations
+		// about the username and the password.
+		usernameCorrect := crypto.ConstantTimeCmp(username, config.Opts.MetricsUsername())
+		passwordCorrect := crypto.ConstantTimeCmp(password, config.Opts.MetricsPassword())
+		if !usernameCorrect || !passwordCorrect {
 			slog.Warn("Metrics endpoint accessed with invalid username or password",
 			slog.Warn("Metrics endpoint accessed with invalid username or password",
 				slog.Bool("authentication_failed", true),
 				slog.Bool("authentication_failed", true),
 				slog.String("client_ip", clientIP),
 				slog.String("client_ip", clientIP),