Harden CHORUS security and messaging stack
This commit is contained in:
95
pkg/shhh/sentinel_test.go
Normal file
95
pkg/shhh/sentinel_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package shhh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type recordingSink struct {
|
||||
events []AuditEvent
|
||||
}
|
||||
|
||||
func (r *recordingSink) RecordRedaction(_ context.Context, event AuditEvent) {
|
||||
r.events = append(r.events, event)
|
||||
}
|
||||
|
||||
func TestRedactText_DefaultRules(t *testing.T) {
|
||||
sentinel, err := NewSentinel(Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
input := "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.secret"
|
||||
redacted, findings := sentinel.RedactText(context.Background(), input, map[string]string{"source": "http.request.headers.authorization"})
|
||||
|
||||
require.Equal(t, "Authorization: Bearer [REDACTED]", redacted)
|
||||
require.Len(t, findings, 1)
|
||||
require.Equal(t, "bearer-token", findings[0].Rule)
|
||||
require.Equal(t, 1, findings[0].Count)
|
||||
require.NotEmpty(t, findings[0].Locations)
|
||||
|
||||
snapshot := sentinel.StatsSnapshot()
|
||||
require.Equal(t, uint64(1), snapshot.TotalScans)
|
||||
require.Equal(t, uint64(1), snapshot.TotalFindings)
|
||||
require.Equal(t, uint64(1), snapshot.PerRuleFindings["bearer-token"])
|
||||
}
|
||||
|
||||
func TestRedactMap_NestedStructures(t *testing.T) {
|
||||
sentinel, err := NewSentinel(Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
payload := map[string]any{
|
||||
"config": map[string]any{
|
||||
"api_key": "API_KEY=1234567890ABCDEFG",
|
||||
},
|
||||
"tokens": []any{
|
||||
"sk-test1234567890ABCDEF",
|
||||
map[string]any{"refresh": "refresh_token=abcdef12345"},
|
||||
},
|
||||
}
|
||||
|
||||
findings := sentinel.RedactMap(context.Background(), payload)
|
||||
require.NotEmpty(t, findings)
|
||||
|
||||
config := payload["config"].(map[string]any)
|
||||
require.Equal(t, "API_KEY=[REDACTED]", config["api_key"])
|
||||
|
||||
tokens := payload["tokens"].([]any)
|
||||
require.Equal(t, "[REDACTED]", tokens[0])
|
||||
|
||||
inner := tokens[1].(map[string]any)
|
||||
require.Equal(t, "refresh_token=[REDACTED]", inner["refresh"])
|
||||
|
||||
total := 0
|
||||
for _, finding := range findings {
|
||||
total += finding.Count
|
||||
}
|
||||
require.Equal(t, 3, total)
|
||||
}
|
||||
|
||||
func TestAuditSinkReceivesEvents(t *testing.T) {
|
||||
sink := &recordingSink{}
|
||||
cfg := Config{
|
||||
DisableDefaultRules: true,
|
||||
CustomRules: []RuleConfig{
|
||||
{
|
||||
Name: "custom-secret",
|
||||
Pattern: `(secret\s*=\s*)([A-Za-z0-9]{6,})`,
|
||||
ReplacementTemplate: "$1[REDACTED]",
|
||||
Severity: SeverityHigh,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
sentinel, err := NewSentinel(cfg, WithAuditSink(sink))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, findings := sentinel.RedactText(context.Background(), "secret=mysecretvalue", map[string]string{"source": "test"})
|
||||
require.Len(t, findings, 1)
|
||||
require.Equal(t, 1, findings[0].Count)
|
||||
|
||||
require.Len(t, sink.events, 1)
|
||||
require.Equal(t, "custom-secret", sink.events[0].Rule)
|
||||
require.NotEmpty(t, sink.events[0].Hash)
|
||||
require.Equal(t, "test", sink.events[0].Path)
|
||||
}
|
||||
Reference in New Issue
Block a user