Skip to content

Commit 6e2d0f4

Browse files
hitalinclaude
andcommitted
fix: APIトークンの定数時間比較とCSPRNG生成に変更
timing attackを防止するため、auth_middlewareのBearer Token比較を subtle::ConstantTimeEqによる定数時間実装に変更。 トークン生成もUUID v4 (122-bit)からCSPRNG 256-bit hexに強化。 - auth_middleware: == → ct_eq (subtle クレート) - main.rs: uuid::Uuid::new_v4() → rand::random::<[u8; 32]>() - 認証失敗時のtracing::warnログを追加 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a60f821 commit 6e2d0f4

4 files changed

Lines changed: 16 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ thiserror = "2.0.18"
2121
tracing = "0.1"
2222
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
2323
zeroize = "1"
24+
subtle = "2"
25+
rand = "0.9"
2426
keyring-core = { version = "0.7", optional = true }
2527
axum = "0.8"
2628
tower-http = { version = "0.6", features = ["cors"] }

src/http_server.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use axum::{
99
routing::{delete, get, post},
1010
Json, Router,
1111
};
12+
use subtle::ConstantTimeEq;
1213
use futures_util::stream::Stream;
1314
use serde::Deserialize;
1415
use serde_json::{json, Value};
@@ -201,8 +202,13 @@ async fn auth_middleware(
201202
.and_then(|v| v.strip_prefix("Bearer "));
202203

203204
match token {
204-
Some(t) if t == state.api_token => Ok(next.run(req).await),
205-
_ => Err(ApiError::unauthorized().into_response()),
205+
Some(t) if bool::from(t.as_bytes().ct_eq(state.api_token.as_bytes())) => {
206+
Ok(next.run(req).await)
207+
}
208+
_ => {
209+
tracing::warn!(uri = %req.uri(), "unauthorized API access attempt");
210+
Err(ApiError::unauthorized().into_response())
211+
}
206212
}
207213
}
208214

src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ async fn run_daemon(port: u16) {
6666
let emitter = Arc::new(EventBusEmitter::new(event_bus.clone()));
6767
let _streaming = StreamingManager::new(emitter, event_bus.clone(), db.clone());
6868

69-
let api_token = uuid::Uuid::new_v4().to_string();
69+
let api_token: String = rand::random::<[u8; 32]>()
70+
.iter()
71+
.map(|b| format!("{b:02x}"))
72+
.collect();
7073
let token_path = data_dir.join("api-token");
7174
std::fs::write(&token_path, &api_token).expect("Failed to write API token");
7275
#[cfg(unix)]

0 commit comments

Comments
 (0)