mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-25 07:15:01 +03:00
perf(auth): look up api tokens by their hash index (#6915)
Every bearer-authenticated request, including each node-sync call, loaded all enabled api_tokens rows and compared each stored SHA-256 hash in constant time. Tokens are stored hashed, so the database can compare hashes directly: a timing leak there reveals only a stored hash, which cannot authenticate. The lookup is now one indexed seek on idx_api_tokens_token, which AutoMigrate creates from the model tag on new and existing databases; scope and expiry are still checked afterwards.
This commit is contained in:
@@ -21,7 +21,7 @@ func TestAutoMigrateCreatesHotPathIndexes(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.ClientRecord{}, &xray.ClientTraffic{}, &model.ClientGlobalTraffic{}); err != nil {
|
||||
if err := db.AutoMigrate(&model.ClientRecord{}, &xray.ClientTraffic{}, &model.ClientGlobalTraffic{}, &model.ApiToken{}); err != nil {
|
||||
t.Fatalf("automigrate: %v", err)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ func TestAutoMigrateCreatesHotPathIndexes(t *testing.T) {
|
||||
{&xray.ClientTraffic{}, "idx_client_traffics_inbound"},
|
||||
{&xray.ClientTraffic{}, "idx_client_traffics_renew"},
|
||||
{&model.ClientGlobalTraffic{}, "idx_client_global_email"},
|
||||
{&model.ApiToken{}, "idx_api_tokens_token"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if !db.Migrator().HasIndex(c.model, c.index) {
|
||||
|
||||
@@ -178,7 +178,7 @@ func IsNodeSyncApiScope(s string) bool {
|
||||
type ApiToken struct {
|
||||
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
|
||||
Name string `json:"name" gorm:"uniqueIndex;not null"`
|
||||
Token string `json:"token" gorm:"not null"` // SHA-256 hash; the plaintext is shown only once at creation
|
||||
Token string `json:"token" gorm:"not null;index:idx_api_tokens_token"` // SHA-256 hash; the plaintext is shown only once at creation
|
||||
Enabled bool `json:"enabled" gorm:"default:true"`
|
||||
CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime"`
|
||||
Scope string `json:"scope" gorm:"not null;default:admin"`
|
||||
|
||||
Reference in New Issue
Block a user