feat(iam): tambahkan CSPRNG (OsRng) untuk token state/PKCE
This commit is contained in:
Generated
+2
@@ -4772,7 +4772,9 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
|
"rand_core 0.6.4",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -18,3 +18,5 @@ tracing.workspace = true
|
|||||||
url.workspace = true
|
url.workspace = true
|
||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
|
hex.workspace = true
|
||||||
|
rand_core = { version = "0.6", features = ["getrandom"] }
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
pub mod http;
|
pub mod http;
|
||||||
pub mod persistence;
|
pub mod persistence;
|
||||||
|
pub mod rng;
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//! Cryptographically secure random-token generation for OAuth CSRF state
|
||||||
|
//! tokens and PKCE verifiers.
|
||||||
|
use rand_core::{OsRng, RngCore};
|
||||||
|
|
||||||
|
/// Generate `n_bytes` of CSPRNG output, hex-encoded.
|
||||||
|
///
|
||||||
|
/// Why: the previous implementation derived "randomness" from
|
||||||
|
/// `SystemTime::now()` XORed with a monotonic counter — predictable given
|
||||||
|
/// a bounded guess at request time, which undermines both CSRF `state`
|
||||||
|
/// and PKCE verifier unpredictability. `OsRng` draws from the OS entropy
|
||||||
|
/// source (`getrandom`/`/dev/urandom` equivalent) and is the same
|
||||||
|
/// primitive already used correctly for password-salt generation in
|
||||||
|
/// `zesdex-libs::password::hash_password`.
|
||||||
|
///
|
||||||
|
/// Return: a lowercase hex string of length `2 * n_bytes`.
|
||||||
|
pub fn secure_token_hex(n_bytes: usize) -> String {
|
||||||
|
let mut buf = vec![0u8; n_bytes];
|
||||||
|
OsRng.fill_bytes(&mut buf);
|
||||||
|
hex::encode(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secure_token_hex_produces_correct_length() {
|
||||||
|
assert_eq!(secure_token_hex(16).len(), 32);
|
||||||
|
assert_eq!(secure_token_hex(32).len(), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secure_token_hex_is_not_constant() {
|
||||||
|
let a = secure_token_hex(16);
|
||||||
|
let b = secure_token_hex(16);
|
||||||
|
assert_ne!(a, b, "two consecutive calls must not produce the same token");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user