Scan now reports PrivacyScan.Sanitized {detected, markers, strong, files,
evidence}. SanitizationMarkers recognises a value slot filled with one
repeated placeholder + separators (xxxxx.xxxx.xx, x@xxxx.xxxx.xx,
000.00.00.0, a decoy timezone) - it matches the shape, not the literal "x",
so evolving the redaction mechanism still trips it.
detected requires corroboration: strong>=2, or strong>=1 && markers>=3, or
markers>=4. A single filler-looking token is reported (markers:1) but never
asserted as sanitized, so a partial future pass or a coincidence does not
read as "done". 0.0.0.0 / 000 / UTC / Etc/UTC are too plausibly intentional
and do not count.
UI: the Customer-data panel shows "файл уже обезличен" and hides the
sanitize button when detected.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jDYM1nnoZZ3vFz23DDaV1
70 lines
2.2 KiB
Go
70 lines
2.2 KiB
Go
package privacy
|
|
|
|
import "testing"
|
|
|
|
func TestIsGenericFiller(t *testing.T) {
|
|
yes := []string{"xxxxx.xxxx.xx", "x@xxxx.xxxx.xx", "xxxxxx/xxxxxx", "000.00.00.0", "00.00.00.00"}
|
|
no := []string{"0.0.0.0", "000", "corp.acme.ru", "192.0.2.0", "10.20.30.40", "example.local", "x", "xx"}
|
|
for _, s := range yes {
|
|
if !isGenericFiller(s) {
|
|
t.Errorf("isGenericFiller(%q) = false, want true", s)
|
|
}
|
|
}
|
|
for _, s := range no {
|
|
if isGenericFiller(s) {
|
|
t.Errorf("isGenericFiller(%q) = true, want false", s)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSanitizationMarkers_Line(t *testing.T) {
|
|
strong := 0
|
|
for _, m := range SanitizationMarkers("domain xxxxxxx.xxxxx") {
|
|
if m.Strong {
|
|
strong++
|
|
}
|
|
}
|
|
if strong == 0 {
|
|
t.Fatal("redacted resolv domain not detected as a strong marker")
|
|
}
|
|
if len(SanitizationMarkers("domain corp.acme.ru")) != 0 {
|
|
t.Fatal("real domain flagged as a sanitization marker")
|
|
}
|
|
if len(SanitizationMarkers("gateway 0.0.0.0 unset")) != 0 {
|
|
t.Fatal("0.0.0.0 flagged as a marker")
|
|
}
|
|
}
|
|
|
|
func TestScan_SanitizedDetectionNeedsCorroboration(t *testing.T) {
|
|
// One lone filler-looking token: reported, but not "detected".
|
|
rep := Scan([]File{{Path: "a.log", Content: []byte("host is xxxxx.xxxx.xx today\nnothing else\n")}})
|
|
if rep == nil || rep.Sanitized == nil {
|
|
t.Fatal("expected a sanitized report")
|
|
}
|
|
if rep.Sanitized.Detected {
|
|
t.Fatalf("a single marker must not read as sanitized: %+v", rep.Sanitized)
|
|
}
|
|
if rep.Sanitized.Markers != 1 {
|
|
t.Fatalf("markers = %d, want 1", rep.Sanitized.Markers)
|
|
}
|
|
|
|
// Two strong markers in two files -> detected.
|
|
rep2 := Scan([]File{
|
|
{Path: "resolv.conf", Content: []byte("domain xxxxxxx.xxxxx\n")},
|
|
{Path: "nsupdate_temp", Content: []byte("update add xxxxx.xxxxxxx.xx 0 A 10.0.0.1\n")},
|
|
})
|
|
if rep2 == nil || rep2.Sanitized == nil || !rep2.Sanitized.Detected {
|
|
t.Fatalf("two-file sanitized dump not detected: %+v", rep2.Sanitized)
|
|
}
|
|
}
|
|
|
|
func TestScan_UnsanitizedHasNoSanitizedReport(t *testing.T) {
|
|
rep := Scan([]File{{Path: "resolv.conf", Content: []byte("domain corp.acme.ru\nnameserver 10.0.0.1\n")}})
|
|
if rep == nil {
|
|
t.Fatal("nil report")
|
|
}
|
|
if rep.Sanitized != nil {
|
|
t.Fatalf("clean dump got a sanitized report: %+v", rep.Sanitized)
|
|
}
|
|
}
|