Skip to content

Commit 2e6c52b

Browse files
authored
Merge pull request #238 from rararulab/issue-233-timing-attack
fix(ingestor): use constant-time comparison for URL signatures (#233)
2 parents f5f702d + 5b98dd9 commit 2e6c52b

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

crates/core/src/domain/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use processing_task::{ProcessingTask, TaskStatus};
1313
#[doc(inline)]
1414
pub use share_link::ShareLink;
1515
#[doc(inline)]
16-
pub use token::{ConnectionToken, TokenAction, TokenError};
16+
pub use token::{ConnectionToken, TokenAction, TokenError, constant_time_eq};
1717
#[doc(inline)]
1818
pub use video::{Video, VideoStatus};
1919

crates/core/src/domain/token.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,11 @@ fn compute_hmac(secret: &[u8], data: &[u8]) -> String {
159159
hex::encode(mac.finalize().into_bytes())
160160
}
161161

162-
/// Constant-time comparison to prevent timing attacks.
163-
fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
162+
/// Constant-time byte-slice comparison to prevent timing attacks.
163+
///
164+
/// Uses XOR folding so that execution time is independent of where
165+
/// (or whether) the slices differ.
166+
pub fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
164167
if a.len() != b.len() {
165168
return false;
166169
}

crates/ingestor/src/handlers.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,9 @@ fn verify_upload_url(secret: &[u8], video_id: &str, part: u64, exp: u64, sig: &s
290290
mac.update(format!("{video_id}:{part}:{exp}").as_bytes());
291291
let expected = hex::encode(mac.finalize().into_bytes());
292292

293-
if expected != sig {
293+
// Use constant-time comparison to prevent timing attacks on signature
294+
// verification
295+
if !stream_core::domain::constant_time_eq(expected.as_bytes(), sig.as_bytes()) {
294296
return Err(IngestorError::Unauthorized);
295297
}
296298
Ok(())

0 commit comments

Comments
 (0)