webhook: compare secret in constant time
payload.secret != expected_secret short-circuits on the first differing byte, which leaks timing information about how many leading bytes of a guess are correct. Use subtle::ConstantTimeEq instead.
This commit is contained in:
parent
85369069c3
commit
1473e726f3
2 changed files with 5 additions and 1 deletions
|
|
@ -18,6 +18,7 @@ reqwest = {
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
sha2 = "0.10"
|
||||
subtle = "2"
|
||||
sqlx = {
|
||||
version = "0.8",
|
||||
features = [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use axum::{extract::State, http::StatusCode, response::IntoResponse};
|
||||
use serde::Deserialize;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
|
|
@ -28,7 +29,9 @@ pub async fn receive(
|
|||
.into_response();
|
||||
};
|
||||
|
||||
if payload.secret != expected_secret {
|
||||
let secret_matches = payload.secret.as_bytes().ct_eq(expected_secret.as_bytes());
|
||||
|
||||
if !bool::from(secret_matches) {
|
||||
tracing::warn!("received webhook with invalid secret");
|
||||
|
||||
return (StatusCode::UNAUTHORIZED, "invalid webhook secret").into_response();
|
||||
|
|
|
|||
Loading…
Reference in a new issue