From a28c306b2368854346a389e56a2ae3fa5582a0df Mon Sep 17 00:00:00 2001 From: Extra Small Date: Wed, 11 Mar 2026 04:31:43 -0700 Subject: [PATCH] use constant-time comparison for auth token validation (#7730) Signed-off-by: Extra Small Co-authored-by: extrasmall0 --- crates/goose-server/Cargo.toml | 1 + crates/goose-server/src/auth.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/goose-server/Cargo.toml b/crates/goose-server/Cargo.toml index 6321f40afd..e7ad479b53 100644 --- a/crates/goose-server/Cargo.toml +++ b/crates/goose-server/Cargo.toml @@ -46,6 +46,7 @@ tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] url = { workspace = true } rand = "0.9.2" hex = "0.4.3" +subtle = "2.6" socket2 = "0.6.1" fs2 = { workspace = true } rustls = { version = "0.23", features = ["aws_lc_rs"] } diff --git a/crates/goose-server/src/auth.rs b/crates/goose-server/src/auth.rs index 41790a9351..66a2d2a1ee 100644 --- a/crates/goose-server/src/auth.rs +++ b/crates/goose-server/src/auth.rs @@ -4,6 +4,7 @@ use axum::{ middleware::Next, response::Response, }; +use subtle::ConstantTimeEq; pub async fn check_token( State(state): State, @@ -23,7 +24,9 @@ pub async fn check_token( .and_then(|value| value.to_str().ok()); match secret_key { - Some(key) if key == state => Ok(next.run(request).await), + Some(key) if bool::from(key.as_bytes().ct_eq(state.as_bytes())) => { + Ok(next.run(request).await) + } _ => Err(StatusCode::UNAUTHORIZED), } }