Skip to content

Use crypto/rand instead of math/rand for random string generation#145

Closed
kblissett wants to merge 1 commit intoSecureAuthCorp:masterfrom
kblissett:master
Closed

Use crypto/rand instead of math/rand for random string generation#145
kblissett wants to merge 1 commit intoSecureAuthCorp:masterfrom
kblissett:master

Conversation

@kblissett
Copy link

@kblissett kblissett commented Jan 26, 2026

This adheres to security best practices by using cryptographically secure random values for OAuth2 state parameters and PKCE code verifiers. Resolves #144

This adheres to security best practices by using cryptographically secure random values for OAuth2 state parameters and PKCE code verifiers.
@mbilski mbilski enabled auto-merge (squash) January 26, 2026 18:19
@mbilski mbilski disabled auto-merge January 26, 2026 18:19
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates from math/rand to crypto/rand for generating random strings used in OAuth2 security-critical contexts (PKCE code verifiers and JWT assertion JTI claims), addressing a security best practice issue raised in #144.

Changes:

  • Replaced math/rand with crypto/rand for cryptographically secure random generation
  • Simplified the implementation by removing the global random generator and init() function
  • Changed the character set from []rune to []byte for direct byte manipulation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

func RandomString(n int) string {
b := make([]rune, n)
b := make([]byte, n)
rand.Read(b)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error return value from rand.Read() is being ignored. According to the crypto/rand documentation, rand.Read can return an error if the underlying system fails to provide sufficient randomness. This function should handle the error appropriately, either by returning an error to the caller or by panicking if random generation fails, since generating predictable values would be a security issue for OAuth2 state parameters and PKCE code verifiers.

Suggested change
rand.Read(b)
if _, err := rand.Read(b); err != nil {
panic("oauth2: failed to generate secure random string: " + err.Error())
}

Copilot uses AI. Check for mistakes.
Comment on lines 13 to +14
for i := range b {
b[i] = letter[r.Intn(len(letter))]
b[i] = letter[b[i]%byte(len(letter))]
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The modulo operation creates a slight bias in character selection. Since 256 % 62 = 8, the first 8 characters of the alphabet have a slightly higher probability of being selected. While the practical security impact is minimal for the current use cases (43-character PKCE verifiers and 20-character JTI claims), consider using a rejection sampling approach: generate a random byte, and if it's >= 248 (the largest multiple of 62 that fits in a byte), discard it and generate a new one. This ensures uniform distribution across all characters.

Copilot uses AI. Check for mistakes.
@mbilski
Copy link
Contributor

mbilski commented Feb 4, 2026

I made the linter suggested fixes in #148

@mbilski mbilski closed this Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider using crypto/rand for PKCE code_verifier and jti generation

3 participants