99 "fmt"
1010 "log"
1111 "math/big"
12- mathrand "math/rand"
1312 "sync"
1413 "time"
1514
@@ -187,15 +186,15 @@ func leaseCheckWait(s *Secret, retryCount int) time.Duration {
187186 sleep = sleep / 3.0
188187
189188 // Use some randomness so many clients do not hit Vault simultaneously.
190- sleep = sleep * (mathrand . Float64 () + 1 ) / 2.0
189+ sleep = sleep * (secureRandomFloat64 () + 1 ) / 2.0
191190 } else if ! rotatingSecret {
192191 // If the secret doesn't have a rotation period, this is a non-renewable leased
193192 // secret.
194193 // For non-renewable leases set the renew duration to use much of the secret
195194 // lease as possible. Use a stagger over the configured threshold
196195 // fraction of the lease duration so that many clients do not hit
197196 // Vault simultaneously.
198- finalFraction := VaultLeaseRenewalThreshold + (mathrand . Float64 ()- 0.5 )* 0.1
197+ finalFraction := VaultLeaseRenewalThreshold + (secureRandomFloat64 ()- 0.5 )* 0.1
199198 if finalFraction >= 1.0 || finalFraction <= 0.0 {
200199 // If the fraction randomly winds up outside of (0.0-1.0), clamp
201200 // back down to the VaultLeaseRenewalThreshold provided by the user,
@@ -210,19 +209,24 @@ func leaseCheckWait(s *Secret, retryCount int) time.Duration {
210209 return time .Duration (sleep )
211210}
212211
213- // jitter adds randomness to a duration to prevent thundering herd.
214- // It reduces the duration by up to maxJitter (10%) randomly using crypto/rand.
215- // using this to fix CWE-338: Use of Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)
216- func jitter (t time.Duration ) time.Duration {
217- // Generate cryptographically secure random value between 0.0 and 1.0
212+ // secureRandomFloat64 generates a cryptographically secure random float64 in [0.0, 1.0).
213+ // This is thread-safe and used to fix CWE-338.
214+ func secureRandomFloat64 () float64 {
218215 max := big .NewInt (1000000 )
219216 n , err := cryptorand .Int (cryptorand .Reader , max )
220217 if err != nil {
221- // Fallback to no jitter if crypto/rand fails
222- log .Printf ("[WARN] Failed to generate secure random jitter : %v" , err )
223- return t
218+ // Fallback to 0.5 if crypto/rand fails (rare but possible)
219+ log .Printf ("[WARN] Failed to generate secure random number : %v" , err )
220+ return 0.5
224221 }
225- randomFloat := float64 (n .Int64 ()) / 1000000.0
222+ return float64 (n .Int64 ()) / 1000000.0
223+ }
224+
225+ // jitter adds randomness to a duration to prevent thundering herd.
226+ // It reduces the duration by up to maxJitter (10%) randomly using crypto/rand.
227+ // This function is thread-safe.
228+ func jitter (t time.Duration ) time.Duration {
229+ randomFloat := secureRandomFloat64 ()
226230 f := float64 (t ) * (1.0 - maxJitter * randomFloat )
227231 return time .Duration (f )
228232}
0 commit comments