security: remediate review B findings

This commit is contained in:
kory
2026-10-03 01:37:02 +08:00
parent ca4d54d5b3
commit 56b05b11d9
11 changed files with 674 additions and 35 deletions
+21 -3
View File
@@ -8,6 +8,7 @@ import (
"time"
jwt "github.com/golang-jwt/jwt/v4"
"golang.org/x/crypto/bcrypt"
)
type PermMask uint8
@@ -86,8 +87,10 @@ func ParseRules(values []string) (*Manager, error) {
}
func (m *Manager) Authenticate(user, pwd string) *Account {
if a, ok := m.Accounts[user]; ok && (a.Enabled || a.PasswordHash == "") && (a.Password == pwd || a.PasswordHash == PasswordHash(pwd)) {
return a
if a, ok := m.Accounts[user]; ok && (a.Enabled || a.PasswordHash == "") {
if a.Password == pwd || VerifyPasswordHash(a.PasswordHash, pwd) {
return a
}
}
if user == "" && pwd == "" {
return m.Guest
@@ -95,8 +98,23 @@ func (m *Manager) Authenticate(user, pwd string) *Account {
return nil
}
func PasswordHash(password string) string {
h, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return ""
}
return string(h)
}
func VerifyPasswordHash(stored, password string) bool {
if stored == "" {
return false
}
if strings.HasPrefix(stored, "$2a$") || strings.HasPrefix(stored, "$2b$") || strings.HasPrefix(stored, "$2y$") {
return bcrypt.CompareHashAndPassword([]byte(stored), []byte(password)) == nil
}
// Legacy unsalted SHA-256 hashes remain readable for one migration cycle.
h := sha256.Sum256([]byte(password))
return hex.EncodeToString(h[:])
return hex.EncodeToString(h[:]) == stored
}
func (a *Account) MaskFor(path string) PermMask {
+31
View File
@@ -0,0 +1,31 @@
package auth
import (
"crypto/sha256"
"encoding/hex"
"testing"
)
func TestPasswordHashUsesBcryptAndVerifies(t *testing.T) {
hash := PasswordHash("correct horse battery staple")
if len(hash) < 4 || (hash[0:4] != "$2a$" && hash[0:4] != "$2b$") {
t.Fatalf("hash=%q is not bcrypt", hash)
}
if !VerifyPasswordHash(hash, "correct horse battery staple") {
t.Fatal("bcrypt password did not verify")
}
if VerifyPasswordHash(hash, "wrong") {
t.Fatal("wrong password verified")
}
}
func TestLegacySHA256PasswordStillVerifies(t *testing.T) {
sum := sha256.Sum256([]byte("legacy-pass"))
hash := hex.EncodeToString(sum[:])
if !VerifyPasswordHash(hash, "legacy-pass") {
t.Fatal("legacy hash did not verify")
}
if VerifyPasswordHash(hash, "wrong") {
t.Fatal("wrong legacy password verified")
}
}