Use Content-Security-Policy: script nonce (#37232)

Fix #305
This commit is contained in:
wxiaoguang
2026-04-16 04:07:57 +08:00
committed by GitHub
parent 2644bb8490
commit 82bfde2a37
18 changed files with 134 additions and 52 deletions
+34 -2
View File
@@ -6,11 +6,14 @@ package util
import (
"bytes"
"crypto/rand"
"encoding/hex"
"fmt"
"math/big"
rand2 "math/rand/v2"
"slices"
"strconv"
"strings"
"sync"
"golang.org/x/text/cases"
"golang.org/x/text/language"
@@ -85,10 +88,39 @@ func CryptoRandomString(length int64) (string, error) {
// CryptoRandomBytes generates `length` crypto bytes
// This differs from CryptoRandomString, as each byte in CryptoRandomString is generated by [0,61] range
// This function generates totally random bytes, each byte is generated by [0,255] range
// TODO: it never fails, remove the "error" in the future
func CryptoRandomBytes(length int64) ([]byte, error) {
buf := make([]byte, length)
_, err := rand.Read(buf)
return buf, err
if _, err := rand.Read(buf); err != nil {
panic(err) // this should never happen, "rand.Read" never fails
}
return buf, nil
}
var chaCha8RandPool = sync.OnceValue(func() *sync.Pool {
return &sync.Pool{
New: func() any {
var buf [32]byte
_, _ = rand.Read(buf[:])
return rand2.NewChaCha8(buf)
},
}
})
func FastCryptoRandomBytes(length int) []byte {
// ChaCha8 is about 20x times faster than system's crypto/rand.
// It is suitable for UUIDs, session IDs, etc
pool := chaCha8RandPool()
chaCha8Rand := pool.Get().(*rand2.ChaCha8)
defer pool.Put(chaCha8Rand)
buf := make([]byte, length)
_, _ = chaCha8Rand.Read(buf)
return buf
}
func FastCryptoRandomHex(length int) string {
buf := FastCryptoRandomBytes(length / 2)
return hex.EncodeToString(buf)
}
// ToLowerASCII returns s with all ASCII letters mapped to their lower case.