fix: sanitize workbench facts cache payloads
This commit is contained in:
@@ -193,7 +193,7 @@ func TestFactsCacheStorablePayloadRemovesRuntimeOnlySecretKeys(t *testing.T) {
|
|||||||
"secretMaterialStored": false,
|
"secretMaterialStored": false,
|
||||||
"persistence": map[string]any{"cache": map[string]any{"secretMaterialStored": false}},
|
"persistence": map[string]any{"cache": map[string]any{"secretMaterialStored": false}},
|
||||||
"facts": map[string]any{
|
"facts": map[string]any{
|
||||||
"traceEvents": []any{map[string]any{"traceId": "trc_1", "projectedSeq": 1, "valuesRedacted": true}},
|
"traceEvents": []any{map[string]any{"traceId": "trc_1", "projectedSeq": 1, "providerPayload": map[string]any{"raw": true}, "stdout": "internal", "valuesRedacted": true}},
|
||||||
},
|
},
|
||||||
"valuesRedacted": true,
|
"valuesRedacted": true,
|
||||||
}
|
}
|
||||||
@@ -204,6 +204,14 @@ func TestFactsCacheStorablePayloadRemovesRuntimeOnlySecretKeys(t *testing.T) {
|
|||||||
if _, ok := stored["persistence"]; ok {
|
if _, ok := stored["persistence"]; ok {
|
||||||
t.Fatalf("facts storable payload kept persistence: %#v", stored)
|
t.Fatalf("facts storable payload kept persistence: %#v", stored)
|
||||||
}
|
}
|
||||||
|
traceEvents := objectMap(stored["facts"])["traceEvents"].([]any)
|
||||||
|
traceEvent := objectMap(traceEvents[0])
|
||||||
|
if _, ok := traceEvent["providerPayload"]; ok {
|
||||||
|
t.Fatalf("facts storable payload kept providerPayload: %#v", traceEvent)
|
||||||
|
}
|
||||||
|
if _, ok := traceEvent["stdout"]; ok {
|
||||||
|
t.Fatalf("facts storable payload kept stdout: %#v", traceEvent)
|
||||||
|
}
|
||||||
entry := factsCacheEntry{CachedAt: time.Now().UTC().Format(time.RFC3339Nano), Payload: stored, PayloadBytes: 128, TTLMillis: 300000, ValuesRedacted: true}
|
entry := factsCacheEntry{CachedAt: time.Now().UTC().Format(time.RFC3339Nano), Payload: stored, PayloadBytes: 128, TTLMillis: 300000, ValuesRedacted: true}
|
||||||
if _, err := cachePayloadBytes(entry, 4096); err != nil {
|
if _, err := cachePayloadBytes(entry, 4096); err != nil {
|
||||||
t.Fatalf("storable facts payload rejected: %v", err)
|
t.Fatalf("storable facts payload rejected: %v", err)
|
||||||
|
|||||||
@@ -543,7 +543,35 @@ func factsCacheStorablePayload(payload map[string]any) map[string]any {
|
|||||||
delete(clone, "cache")
|
delete(clone, "cache")
|
||||||
delete(clone, "persistence")
|
delete(clone, "persistence")
|
||||||
delete(clone, "secretMaterialStored")
|
delete(clone, "secretMaterialStored")
|
||||||
return clone
|
return objectMap(sanitizeFactsCachePayload(clone))
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeFactsCachePayload(value any) any {
|
||||||
|
switch item := value.(type) {
|
||||||
|
case map[string]any:
|
||||||
|
cleaned := map[string]any{}
|
||||||
|
for key, child := range item {
|
||||||
|
if cachePayloadKeyRejected(key) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cleaned[key] = sanitizeFactsCachePayload(child)
|
||||||
|
}
|
||||||
|
return cleaned
|
||||||
|
case []any:
|
||||||
|
cleaned := make([]any, 0, len(item))
|
||||||
|
for _, child := range item {
|
||||||
|
cleaned = append(cleaned, sanitizeFactsCachePayload(child))
|
||||||
|
}
|
||||||
|
return cleaned
|
||||||
|
case []map[string]any:
|
||||||
|
cleaned := make([]any, 0, len(item))
|
||||||
|
for _, child := range item {
|
||||||
|
cleaned = append(cleaned, sanitizeFactsCachePayload(child))
|
||||||
|
}
|
||||||
|
return cleaned
|
||||||
|
default:
|
||||||
|
return value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func factsCacheResponsePayload(payload map[string]any, persistence map[string]any) map[string]any {
|
func factsCacheResponsePayload(payload map[string]any, persistence map[string]any) map[string]any {
|
||||||
|
|||||||
Reference in New Issue
Block a user