From 1497884ce6850dbf3bfad88719026fd20af77feb Mon Sep 17 00:00:00 2001 From: hdbg Date: Mon, 6 Apr 2026 18:27:46 +0200 Subject: [PATCH] fix(server::bootsrapper): token compare is now constant-time --- server/Cargo.lock | 1 + server/crates/arbiter-server/Cargo.toml | 1 + .../arbiter-server/src/actors/bootstrap.rs | 23 ++++++++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/server/Cargo.lock b/server/Cargo.lock index c1c1664..f3138b8 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -760,6 +760,7 @@ dependencies = [ "smlang", "spki", "strum 0.28.0", + "subtle", "test-log", "thiserror 2.0.18", "tokio", diff --git a/server/crates/arbiter-server/Cargo.toml b/server/crates/arbiter-server/Cargo.toml index a94e5b8..20f3f00 100644 --- a/server/crates/arbiter-server/Cargo.toml +++ b/server/crates/arbiter-server/Cargo.toml @@ -60,6 +60,7 @@ arbiter-tokens-registry.path = "../arbiter-tokens-registry" anyhow = "1.0.102" serde_with = "3.18.0" mutants.workspace = true +subtle = "2.6.1" [dev-dependencies] insta = "1.46.3" diff --git a/server/crates/arbiter-server/src/actors/bootstrap.rs b/server/crates/arbiter-server/src/actors/bootstrap.rs index de85d06..cef154a 100644 --- a/server/crates/arbiter-server/src/actors/bootstrap.rs +++ b/server/crates/arbiter-server/src/actors/bootstrap.rs @@ -4,6 +4,7 @@ use diesel_async::RunQueryDsl; use kameo::{Actor, messages}; use rand::{RngExt, distr::Alphanumeric, make_rng, rngs::StdRng}; +use subtle::ConstantTimeEq as _; use thiserror::Error; use crate::db::{self, DatabasePool, schema}; @@ -44,14 +45,14 @@ pub struct Bootstrapper { impl Bootstrapper { pub async fn new(db: &DatabasePool) -> Result { - let mut conn = db.get().await?; + let row_count: i64 = { + let mut conn = db.get().await?; - let row_count: i64 = schema::useragent_client::table - .count() - .get_result(&mut conn) - .await?; - - drop(conn); + schema::useragent_client::table + .count() + .get_result(&mut conn) + .await? + }; let token = if row_count == 0 { let token = generate_token().await?; @@ -69,7 +70,13 @@ impl Bootstrapper { #[message] pub fn is_correct_token(&self, token: String) -> bool { match &self.token { - Some(expected) => *expected == token, + Some(expected) => { + let expected_bytes = expected.as_bytes(); + let token_bytes = token.as_bytes(); + + let choice = expected_bytes.ct_eq(token_bytes); + bool::from(choice) + } None => false, } }