fix: use hashed webhook secrets for constant-time comparison
Store a SHA-256 hash of the webhook secret in a new webhook_secret_hash column. FindAppByWebhookSecret now hashes the incoming secret and queries by hash, eliminating the SQL string comparison timing side-channel. - Add migration 005_add_webhook_secret_hash.sql - Add database.HashWebhookSecret() helper - Backfill existing secrets on startup - Update App model to include WebhookSecretHash in all queries - Update app creation to compute hash at insert time - Add TestHashWebhookSecret unit test - Update all test fixtures to set WebhookSecretHash Closes #13
This commit is contained in:
28
internal/database/hash_test.go
Normal file
28
internal/database/hash_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package database_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"git.eeqj.de/sneak/upaas/internal/database"
|
||||
)
|
||||
|
||||
func TestHashWebhookSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Known SHA-256 of "test-secret"
|
||||
hash := database.HashWebhookSecret("test-secret")
|
||||
assert.Equal(t,
|
||||
"9caf06bb4436cdbfa20af9121a626bc1093c4f54b31c0fa937957856135345b6",
|
||||
hash,
|
||||
)
|
||||
|
||||
// Different secrets produce different hashes
|
||||
hash2 := database.HashWebhookSecret("other-secret")
|
||||
assert.NotEqual(t, hash, hash2)
|
||||
|
||||
// Same secret always produces same hash (deterministic)
|
||||
hash3 := database.HashWebhookSecret("test-secret")
|
||||
assert.Equal(t, hash, hash3)
|
||||
}
|
||||
Reference in New Issue
Block a user