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
29 lines
650 B
Go
29 lines
650 B
Go
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)
|
|
}
|