开源前加固认证与部署契约:加密随机 JWT、改密事务吊销、登录 CSRF,并禁止生产回落 localhost。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -114,14 +114,61 @@ func TestAllowOriginDevAndProd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
const testJWTSecret = "unit-test-jwt-secret-32chars-min!!" // 满足 ≥32,非生产用
|
||||
|
||||
func TestIsWeakJWTSecret(t *testing.T) {
|
||||
if !isWeakJWTSecret("") || !isWeakJWTSecret("short") {
|
||||
t.Fatal("空/过短应判弱")
|
||||
}
|
||||
if !isWeakJWTSecret("abcdefghijklmnopqrstuvwxyzABCDEF") {
|
||||
t.Fatal("旧确定性密钥应判弱")
|
||||
}
|
||||
if !isWeakJWTSecret("change-me") {
|
||||
t.Fatal("占位值应判弱")
|
||||
}
|
||||
if isWeakJWTSecret(testJWTSecret) {
|
||||
t.Fatal("测试强密钥不应判弱")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateSecretNotDeterministic(t *testing.T) {
|
||||
a, err := generateSecret(32)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b, err := generateSecret(32)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if a == b {
|
||||
t.Fatal("连续两次生成不应相同")
|
||||
}
|
||||
if isWeakJWTSecret(a) {
|
||||
t.Fatalf("生成结果被误判为弱: %q", a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRejectsWeakExplicitSecret(t *testing.T) {
|
||||
work := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(work, "app.ini"), []byte("[security]\nJWT_SECRET = change-me\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("JIANG13_WORK_PATH", work)
|
||||
t.Setenv("JWT_SECRET", "")
|
||||
if _, err := Parse(); err == nil {
|
||||
t.Fatal("显式弱密钥应拒绝启动")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSettingsMasterKeyFromIni(t *testing.T) {
|
||||
work := t.TempDir()
|
||||
key := "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE="
|
||||
if err := os.WriteFile(filepath.Join(work, "app.ini"), []byte("[security]\nJWT_SECRET = test-secret-not-for-prod\nSETTINGS_MASTER_KEY = "+key+"\n"), 0600); err != nil {
|
||||
if err := os.WriteFile(filepath.Join(work, "app.ini"), []byte("[security]\nJWT_SECRET = "+testJWTSecret+"\nSETTINGS_MASTER_KEY = "+key+"\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("JIANG13_WORK_PATH", work)
|
||||
t.Setenv("SETTINGS_MASTER_KEY", "")
|
||||
t.Setenv("JWT_SECRET", "")
|
||||
cfg, err := Parse()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -149,7 +196,7 @@ func TestParseSiteURLAndDataDir(t *testing.T) {
|
||||
t.Setenv("SITE_URL", "https://bbs.example.com/")
|
||||
t.Setenv("CORS_ORIGINS", " https://a.example.com ,https://b.example.com/ ")
|
||||
t.Setenv("DATA_DIR", data)
|
||||
t.Setenv("JWT_SECRET", "test-secret-not-for-prod")
|
||||
t.Setenv("JWT_SECRET", testJWTSecret)
|
||||
|
||||
cfg, err := Parse()
|
||||
if err != nil {
|
||||
@@ -210,7 +257,7 @@ func TestEnsureAppIniBackfillsMissingKeys(t *testing.T) {
|
||||
|
||||
func TestParseSiteURLFromIni(t *testing.T) {
|
||||
work := t.TempDir()
|
||||
body := "[security]\nJWT_SECRET = test-secret-not-for-prod\n\n[app]\nDEV_MODE = true\nSITE_URL = https://forum.example.com/\nCORS_ORIGINS = https://a.example.com, https://b.example.com/\n"
|
||||
body := "[security]\nJWT_SECRET = "+testJWTSecret+"\n\n[app]\nDEV_MODE = true\nSITE_URL = https://forum.example.com/\nCORS_ORIGINS = https://a.example.com, https://b.example.com/\n"
|
||||
if err := os.WriteFile(filepath.Join(work, "app.ini"), []byte(body), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user