From 88f9a2bfb81fea3e06768061b15153265468e8a2 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Tue, 13 Oct 2026 18:13:52 +0200 Subject: [PATCH] fix: use crypto/rand for the retry jitter The Bearer scan in CI flags math/rand (weak PRNG rule, CWE-327) and fails the Lint workflow on main. The jitter has no security role, but crypto/rand satisfies the rule without suppressing it. If no randomness is available, the plain backoff is used. --- dispatcher.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dispatcher.go b/dispatcher.go index f243752..ea62811 100644 --- a/dispatcher.go +++ b/dispatcher.go @@ -1,8 +1,9 @@ package slogbetterstack import ( + "crypto/rand" "errors" - "math/rand" + "math/big" "sync" "time" ) @@ -144,11 +145,20 @@ func (d *dispatcher) sendWithRetry(batch []map[string]any) error { // jitter returns a random duration in [d, d+d/2]. Without it, handlers that failed // together (a server outage hitting every replica) would retry in lockstep. // It only ever lengthens the wait, so the backoff stays a lower bound. +// +// crypto/rand is not needed for security here. It keeps the static analysis +// gate (weak PRNG rule) green and costs nothing next to a network retry. func jitter(d time.Duration) time.Duration { spread := d / 2 if spread <= 0 { return d } - return d + time.Duration(rand.Int63n(int64(spread)+1)) + n, err := rand.Int(rand.Reader, big.NewInt(int64(spread)+1)) + if err != nil { + // no randomness available: waiting the plain backoff is still correct + return d + } + + return d + time.Duration(n.Int64()) }