package caddy
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/Wikid82/charon/backend/internal/models"
)
// TestBuildWAFHandler_PathTraversalAttack tests path traversal attempts in ruleset names
// WAF without rules returns nil, so malicious ruleset names that don't have paths should return nil.
func TestBuildWAFHandler_PathTraversalAttack(t *testing.T) {
tests := []struct {
name string
rulesetName string
description string
}{
{
name: "Path traversal in ruleset name",
rulesetName: "../../../etc/passwd",
description: "Ruleset with path traversal should not match any legitimate path",
},
{
name: "Null byte injection",
rulesetName: "rules\x00.conf",
description: "Ruleset with null bytes should not match",
},
{
name: "URL encoded traversal",
rulesetName: "..%2F..%2Fetc%2Fpasswd",
description: "URL encoded path traversal should not match",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
host := &models.ProxyHost{UUID: "test-host"}
rulesets := []models.SecurityRuleSet{{Name: tc.rulesetName}}
// Only provide paths for legitimate rulesets
rulesetPaths := map[string]string{
"owasp-crs": "/app/data/caddy/coraza/rulesets/owasp-crs.conf",
}
secCfg := &models.SecurityConfig{WAFMode: "block", WAFRulesSource: tc.rulesetName}
handler, err := buildWAFHandler(host, rulesets, rulesetPaths, secCfg, true)
require.NoError(t, err)
// Handler should be nil since no matching path exists for malicious names
require.Nil(t, handler, tc.description)
})
}
}
// TestBuildWAFHandler_SQLInjectionInRulesetName tests SQL injection patterns in ruleset names
// WAF without rules returns nil, so malicious patterns without paths should return nil.
func TestBuildWAFHandler_SQLInjectionInRulesetName(t *testing.T) {
sqlInjectionPatterns := []string{
"'; DROP TABLE rulesets; --",
"1' OR '1'='1",
"UNION SELECT * FROM users--",
"admin'/*",
}
for _, pattern := range sqlInjectionPatterns {
t.Run(pattern, func(t *testing.T) {
host := &models.ProxyHost{UUID: "test-host"}
// Create ruleset with malicious name but only provide path for safe ruleset
rulesets := []models.SecurityRuleSet{{Name: pattern}, {Name: "owasp-crs"}}
rulesetPaths := map[string]string{
"owasp-crs": "/app/data/caddy/coraza/rulesets/owasp-crs.conf",
}
secCfg := &models.SecurityConfig{WAFMode: "block", WAFRulesSource: pattern}
handler, err := buildWAFHandler(host, rulesets, rulesetPaths, secCfg, true)
require.NoError(t, err)
// Should return nil since the malicious name has no corresponding path
require.Nil(t, handler, "SQL injection pattern should not produce valid handler")
})
}
}
// TestBuildWAFHandler_XSSInAdvancedConfig tests XSS patterns in advanced_config JSON
func TestBuildWAFHandler_XSSInAdvancedConfig(t *testing.T) {
xssPatterns := []string{
`{"ruleset_name":""}`,
`{"ruleset_name":"
"}`,
`{"ruleset_name":"javascript:alert(1)"}`,
`{"ruleset_name":"