mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-28 22:06:22 +02:00
Release prep: 54 engines, self-hosted signatures, i18n, dashboard updates
This commit is contained in:
parent
694e32be26
commit
41cbfd6e0a
178 changed files with 36008 additions and 399 deletions
225
internal/infrastructure/guard/guard_test.go
Normal file
225
internal/infrastructure/guard/guard_test.go
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
package guard
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testPolicy() *Policy {
|
||||
return &Policy{
|
||||
Version: "1.0",
|
||||
Mode: ModeAudit,
|
||||
Processes: map[string]ProcessPolicy{
|
||||
"soc-ingest": {
|
||||
Description: "test ingest",
|
||||
BlockedSyscalls: []string{"ptrace", "process_vm_readv"},
|
||||
AllowedFiles: []string{"/var/lib/sentinel/data/*", "/tmp/*"},
|
||||
BlockedFiles: []string{"/etc/shadow", "/root/*"},
|
||||
AllowedNetwork: []string{"0.0.0.0:9750"},
|
||||
MaxMemoryMB: 512,
|
||||
},
|
||||
"soc-correlate": {
|
||||
Description: "test correlate — no network",
|
||||
BlockedSyscalls: []string{"ptrace", "execve", "fork", "socket"},
|
||||
AllowedFiles: []string{"/var/lib/sentinel/data/*"},
|
||||
BlockedFiles: []string{"/etc/*", "/root/*"},
|
||||
AllowedNetwork: []string{}, // NONE
|
||||
MaxMemoryMB: 1024,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckSyscall_Blocked(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckSyscall("soc-ingest", 1234, "ptrace")
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for ptrace")
|
||||
}
|
||||
if v.Severity != "CRITICAL" {
|
||||
t.Errorf("severity = %s, want CRITICAL", v.Severity)
|
||||
}
|
||||
if v.Action != "logged" {
|
||||
t.Errorf("action = %s, want logged (audit mode)", v.Action)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckSyscall_Allowed(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckSyscall("soc-ingest", 1234, "read")
|
||||
if v != nil {
|
||||
t.Errorf("unexpected violation for read: %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckSyscall_EnforceMode(t *testing.T) {
|
||||
p := testPolicy()
|
||||
p.Mode = ModeEnforce
|
||||
g := New(p)
|
||||
|
||||
v := g.CheckSyscall("soc-correlate", 5678, "execve")
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for execve")
|
||||
}
|
||||
if v.Action != "blocked" {
|
||||
t.Errorf("action = %s, want blocked (enforce mode)", v.Action)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckSyscall_UnknownProcess(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckSyscall("unknown-proc", 9999, "ptrace")
|
||||
if v != nil {
|
||||
t.Errorf("expected nil for unknown process, got %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckFileAccess_Blocked(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckFileAccess("soc-ingest", 1234, "/etc/shadow")
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for /etc/shadow")
|
||||
}
|
||||
if v.Severity != "HIGH" {
|
||||
t.Errorf("severity = %s, want HIGH", v.Severity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckFileAccess_Allowed(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckFileAccess("soc-ingest", 1234, "/var/lib/sentinel/data/soc.db")
|
||||
if v != nil {
|
||||
t.Errorf("unexpected violation for allowed path: %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckFileAccess_Unauthorized(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckFileAccess("soc-ingest", 1234, "/opt/something/secret")
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for unauthorized path")
|
||||
}
|
||||
if v.Severity != "MEDIUM" {
|
||||
t.Errorf("severity = %s, want MEDIUM", v.Severity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckNetwork_NoNetworkAllowed(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
// soc-correlate has AllowedNetwork: [] — no network at all.
|
||||
v := g.CheckNetwork("soc-correlate", 5678, "8.8.8.8:443")
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for network on correlate")
|
||||
}
|
||||
if v.Severity != "CRITICAL" {
|
||||
t.Errorf("severity = %s, want CRITICAL", v.Severity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckMemory_Exceeded(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckMemory("soc-ingest", 1234, 600) // 600MB > 512MB limit
|
||||
if v == nil {
|
||||
t.Fatal("expected violation for memory exceeded")
|
||||
}
|
||||
if v.Severity != "HIGH" {
|
||||
t.Errorf("severity = %s, want HIGH", v.Severity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckMemory_Within(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
v := g.CheckMemory("soc-ingest", 1234, 400) // 400MB < 512MB
|
||||
if v != nil {
|
||||
t.Errorf("unexpected violation for memory within limit: %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStats(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
g.CheckSyscall("soc-ingest", 1, "ptrace")
|
||||
g.CheckSyscall("soc-ingest", 1, "process_vm_readv")
|
||||
g.CheckFileAccess("soc-ingest", 1, "/etc/shadow")
|
||||
|
||||
stats := g.Stats()
|
||||
if stats.Violations != 3 {
|
||||
t.Errorf("violations = %d, want 3", stats.Violations)
|
||||
}
|
||||
if stats.ByProcess["soc-ingest"] != 3 {
|
||||
t.Errorf("by_process[soc-ingest] = %d, want 3", stats.ByProcess["soc-ingest"])
|
||||
}
|
||||
if stats.ByType["syscall"] != 2 {
|
||||
t.Errorf("by_type[syscall] = %d, want 2", stats.ByType["syscall"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMode(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
if g.CurrentMode() != ModeAudit {
|
||||
t.Fatalf("initial mode = %s, want audit", g.CurrentMode())
|
||||
}
|
||||
|
||||
g.SetMode(ModeEnforce)
|
||||
if g.CurrentMode() != ModeEnforce {
|
||||
t.Errorf("mode after set = %s, want enforce", g.CurrentMode())
|
||||
}
|
||||
}
|
||||
|
||||
func TestViolationHandler(t *testing.T) {
|
||||
g := New(testPolicy())
|
||||
|
||||
var received []Violation
|
||||
g.OnViolation(func(v Violation) {
|
||||
received = append(received, v)
|
||||
})
|
||||
|
||||
g.CheckSyscall("soc-ingest", 1, "ptrace")
|
||||
|
||||
if len(received) != 1 {
|
||||
t.Fatalf("handler received %d violations, want 1", len(received))
|
||||
}
|
||||
if received[0].Type != "syscall" {
|
||||
t.Errorf("type = %s, want syscall", received[0].Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPolicy(t *testing.T) {
|
||||
// Write temp policy file.
|
||||
content := `
|
||||
version: "1.0"
|
||||
mode: enforce
|
||||
processes:
|
||||
test-proc:
|
||||
blocked_syscalls: [ptrace]
|
||||
allowed_files: [/tmp/*]
|
||||
`
|
||||
tmpFile := t.TempDir() + "/test_policy.yaml"
|
||||
if err := writeFile(tmpFile, content); err != nil {
|
||||
t.Fatalf("write temp policy: %v", err)
|
||||
}
|
||||
|
||||
policy, err := LoadPolicy(tmpFile)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadPolicy: %v", err)
|
||||
}
|
||||
if policy.Mode != ModeEnforce {
|
||||
t.Errorf("mode = %s, want enforce", policy.Mode)
|
||||
}
|
||||
if _, ok := policy.Processes["test-proc"]; !ok {
|
||||
t.Error("expected test-proc in processes")
|
||||
}
|
||||
}
|
||||
|
||||
func writeFile(path, content string) error {
|
||||
return os.WriteFile(path, []byte(content), 0644)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue