fix: bound DWH credential digest validation
This commit is contained in:
@@ -111,6 +111,9 @@ func validInstallationID(value string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validDigest(value string) bool {
|
func validDigest(value string) bool {
|
||||||
|
if len(value) != 43 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
decoded, err := base64.RawURLEncoding.DecodeString(value)
|
decoded, err := base64.RawURLEncoding.DecodeString(value)
|
||||||
return err == nil && len(decoded) == 32 && base64.RawURLEncoding.EncodeToString(decoded) == value
|
return err == nil && len(decoded) == 32 && base64.RawURLEncoding.EncodeToString(decoded) == value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ func TestValidateRejectsInvalidSchemaIdentifierAndDigest(t *testing.T) {
|
|||||||
"identifier too long": func(r *Record) { r.InstallationID = "a" + strings.Repeat("b", 63) },
|
"identifier too long": func(r *Record) { r.InstallationID = "a" + strings.Repeat("b", 63) },
|
||||||
"digest padding": func(r *Record) { r.SecretSHA256 += "=" },
|
"digest padding": func(r *Record) { r.SecretSHA256 += "=" },
|
||||||
"digest short": func(r *Record) { r.SecretSHA256 = "AAAA" },
|
"digest short": func(r *Record) { r.SecretSHA256 = "AAAA" },
|
||||||
|
"digest oversized": func(r *Record) { r.SecretSHA256 = strings.Repeat("A", 1024) },
|
||||||
} {
|
} {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
r := validRecord()
|
r := validRecord()
|
||||||
@@ -71,10 +72,21 @@ func TestValidateRejectsInvalidSchemaIdentifierAndDigest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidDigestRejectsOversizedInputWithoutDecoding(t *testing.T) {
|
||||||
|
oversized := strings.Repeat("A", 1024)
|
||||||
|
if validDigest(oversized) {
|
||||||
|
t.Fatal("validDigest() = true, want false")
|
||||||
|
}
|
||||||
|
if allocations := testing.AllocsPerRun(1, func() { validDigest(oversized) }); allocations != 0 {
|
||||||
|
t.Fatalf("validDigest() allocations = %v, want 0 for oversized input", allocations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateRejectsInvalidMetadata(t *testing.T) {
|
func TestValidateRejectsInvalidMetadata(t *testing.T) {
|
||||||
for name, mutate := range map[string]func(*Record){
|
for name, mutate := range map[string]func(*Record){
|
||||||
"description control": func(r *Record) { r.Description = "bad\nmetadata" },
|
"description control": func(r *Record) { r.Description = "bad\nmetadata" },
|
||||||
"description too long": func(r *Record) { r.Description = strings.Repeat("é", 161) },
|
"description invalid utf8": func(r *Record) { r.Description = string([]byte{0xff}) },
|
||||||
|
"description too long": func(r *Record) { r.Description = strings.Repeat("é", 161) },
|
||||||
"reason control": func(r *Record) {
|
"reason control": func(r *Record) {
|
||||||
now := r.CreatedAt.Add(time.Hour)
|
now := r.CreatedAt.Add(time.Hour)
|
||||||
r.RevokedAt = &now
|
r.RevokedAt = &now
|
||||||
@@ -98,11 +110,15 @@ func TestValidateRejectsInvalidMetadata(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidateRejectsInvalidTimesExpiryAndRevocation(t *testing.T) {
|
func TestValidateRejectsInvalidTimesExpiryAndRevocation(t *testing.T) {
|
||||||
for name, mutate := range map[string]func(*Record){
|
for name, mutate := range map[string]func(*Record){
|
||||||
|
"created zero": func(r *Record) { r.CreatedAt = time.Time{} },
|
||||||
|
"expiry before creation": func(r *Record) { at := r.CreatedAt.Add(-time.Second); r.ExpiresAt = &at },
|
||||||
|
"expiry zero": func(r *Record) { at := time.Time{}; r.ExpiresAt = &at },
|
||||||
"created non UTC": func(r *Record) { r.CreatedAt = r.CreatedAt.In(time.FixedZone("CET", 3600)) },
|
"created non UTC": func(r *Record) { r.CreatedAt = r.CreatedAt.In(time.FixedZone("CET", 3600)) },
|
||||||
"expiry non UTC": func(r *Record) { at := r.CreatedAt.Add(time.Hour).In(time.FixedZone("CET", 3600)); r.ExpiresAt = &at },
|
"expiry non UTC": func(r *Record) { at := r.CreatedAt.Add(time.Hour).In(time.FixedZone("CET", 3600)); r.ExpiresAt = &at },
|
||||||
"expiry equals created": func(r *Record) { at := r.CreatedAt; r.ExpiresAt = &at },
|
"expiry equals created": func(r *Record) { at := r.CreatedAt; r.ExpiresAt = &at },
|
||||||
"revoked without reason": func(r *Record) { at := r.CreatedAt.Add(time.Hour); r.RevokedAt = &at },
|
"revoked without reason": func(r *Record) { at := r.CreatedAt.Add(time.Hour); r.RevokedAt = &at },
|
||||||
"reason without revoked": func(r *Record) { r.RevocationReason = "synthetic" },
|
"reason without revoked": func(r *Record) { r.RevocationReason = "synthetic" },
|
||||||
|
"revoked zero": func(r *Record) { at := time.Time{}; r.RevokedAt = &at; r.RevocationReason = "synthetic" },
|
||||||
"revoked non UTC": func(r *Record) {
|
"revoked non UTC": func(r *Record) {
|
||||||
at := r.CreatedAt.Add(time.Hour).In(time.FixedZone("CET", 3600))
|
at := r.CreatedAt.Add(time.Hour).In(time.FixedZone("CET", 3600))
|
||||||
r.RevokedAt = &at
|
r.RevokedAt = &at
|
||||||
|
|||||||
Reference in New Issue
Block a user