Audit finding from #300 (commit 679f9fe)
Severity: medium
Category: auth / timing oracle
File: crates/agent/src/server.rs:235
Obvious fix: yes
Description
bearer_auth_middleware does if provided == expected_token { ... } — Rust's default &str equality is not constant-time. An attacker with timing access to the agent's HTTP endpoint can mount a byte-wise oracle to recover the token character by character.
Impact / Threat
Network-adjacent attacker recovers MCP bearer token by timing repeated requests, gaining full agent control (send messages, manage channels, kick, etc., depending on scope).
Suggested fix
Compare via subtle::ConstantTimeEq (or constant_time_eq crate). Compare the byte slices of equal length; first reject by length-mismatch only after a fixed-cost compare, or by hashing both and comparing fixed-length digests.
Verify
rg "provided == expected_token" crates/agent/src/server.rs
Audit finding from #300 (commit 679f9fe)
Severity: medium
Category: auth / timing oracle
File: crates/agent/src/server.rs:235
Obvious fix: yes
Description
bearer_auth_middlewaredoesif provided == expected_token { ... }— Rust's default&strequality is not constant-time. An attacker with timing access to the agent's HTTP endpoint can mount a byte-wise oracle to recover the token character by character.Impact / Threat
Network-adjacent attacker recovers MCP bearer token by timing repeated requests, gaining full agent control (send messages, manage channels, kick, etc., depending on scope).
Suggested fix
Compare via
subtle::ConstantTimeEq(orconstant_time_eqcrate). Compare the byte slices of equal length; first reject by length-mismatch only after a fixed-cost compare, or by hashing both and comparing fixed-length digests.Verify
rg "provided == expected_token" crates/agent/src/server.rs