-
Notifications
You must be signed in to change notification settings - Fork 264
fix: insecure random ID generation for auth state #2742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,17 @@ | ||
| use rand::{distributions::Alphanumeric, Rng}; | ||
| use rand::rngs::OsRng; | ||
|
|
||
| pub fn generate_random_id(length: usize) -> String { | ||
|
||
| rand::thread_rng() | ||
| .sample_iter(&Alphanumeric) | ||
| .take(length) | ||
| .map(char::from) | ||
| .collect() | ||
| // Use a URL/filename-safe alphabet to avoid control chars, path separators, etc. | ||
| const ALPHABET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789-_"; | ||
|
|
||
| let mut buf = vec![0u8; length]; | ||
| getrandom(&mut buf)?; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| let mut id = String::with_capacity(length); | ||
| for byte in buf { | ||
| let idx = (byte as usize) % ALPHABET.len(); | ||
| id.push(ALPHABET[idx] as char); | ||
| } | ||
|
|
||
| id | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| from qlty_check.src.utils import generate_random_id | ||
|
|
||
| def test_generate_random_id_happy_path(): | ||
| """Test that generate_random_id produces a string of the correct length""" | ||
| result = generate_random_id(10) | ||
| assert isinstance(result, str) | ||
| assert len(result) == 10 | ||
|
|
||
| def test_generate_random_id_edge_cases(): | ||
| """Test generate_random_id with edge case lengths""" | ||
| # Test with length 0 | ||
| result = generate_random_id(0) | ||
| assert isinstance(result, str) | ||
| assert len(result) == 0 | ||
|
|
||
| # Test with larger length | ||
| result = generate_random_id(100) | ||
| assert isinstance(result, str) | ||
| assert len(result) == 100 | ||
|
|
||
| def test_generate_random_id_different_outputs(): | ||
| """Test that generate_random_id produces different outputs on subsequent calls""" | ||
| result1 = generate_random_id(10) | ||
| result2 = generate_random_id(10) | ||
| assert result1 != result2 | ||
|
|
||
| # Ensure both are valid strings of same length | ||
| assert isinstance(result1, str) | ||
| assert isinstance(result2, str) | ||
| assert len(result1) == 10 | ||
| assert len(result2) == 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused import:
rand::rngs::OsRng[clippy:unused_imports]