Merge pull request #937 from chaosoffire-org/feature-random

fix(security): use CSPRNG (crypto/rand) for random number generation
This commit is contained in:
Alireza Ahmadi
2026-01-03 23:49:43 +01:00
committed by GitHub
2 changed files with 43 additions and 17 deletions
+40 -15
View File
@@ -1,30 +1,55 @@
package common
import (
"math/rand"
crand "crypto/rand"
"math/big"
mrand "math/rand"
"sync"
"time"
)
var (
allSeq []rune
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
allSeq []rune = []rune{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
}
fallbackRand = mrand.New(mrand.NewSource(time.Now().UnixNano()))
fallbackMu = sync.Mutex{}
)
func init() {
chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for _, char := range chars {
allSeq = append(allSeq, char)
}
}
func Random(n int) string {
runes := make([]rune, n)
for i := 0; i < n; i++ {
runes[i] = allSeq[rnd.Intn(len(allSeq))]
if n <= 0 || len(allSeq) == 0 {
return ""
}
return string(runes)
result := make([]rune, n)
maxBig := big.NewInt(int64(len(allSeq)))
for i := 0; i < n; i++ {
num, err := crand.Int(crand.Reader, maxBig)
if err != nil {
// fallback
fallbackMu.Lock()
result[i] = allSeq[fallbackRand.Intn(len(allSeq))]
fallbackMu.Unlock()
continue
}
result[i] = allSeq[int(num.Int64())]
}
return string(result)
}
func RandomInt(n int) int {
return rnd.Intn(n)
if n <= 0 {
return 0
}
max := big.NewInt(int64(n))
result, err := crand.Int(crand.Reader, max)
if err != nil {
// fallback
fallbackMu.Lock()
defer fallbackMu.Unlock()
return fallbackRand.Intn(n)
}
return int(result.Int64())
}
+3 -2
View File
@@ -2,7 +2,8 @@ package util
import (
"encoding/json"
"math/rand"
"github.com/alireza0/s-ui/util/common"
"github.com/alireza0/s-ui/database/model"
)
@@ -108,7 +109,7 @@ func addTls(out *map[string]interface{}, tls *model.Tls) {
realityConfig := tlsConfig["reality"].(map[string]interface{})
realityConfig["enabled"] = true
if shortIDs, ok := reality["short_id"].([]interface{}); ok && len(shortIDs) > 0 {
realityConfig["short_id"] = shortIDs[rand.Intn(len(shortIDs))]
realityConfig["short_id"] = shortIDs[common.RandomInt(len(shortIDs))]
}
tlsConfig["reality"] = realityConfig
}