Files
SamWaf/wafenginecore/header_detect_test.go
T
samwaf 24227923e8 feat: strengthen WAF detection coverage and gate the new inspection paths
Detection engine:
- Normalize request data (body, cookies, form and JSON values, request headers)
  before inspection instead of only the URL query string, so encoded variants
  are evaluated consistently.
- Extend XSS / SQLi / command-injection inspection to request bodies and to
  custom request headers; bodies and headers are scanned per value rather than
  as one blob to keep false positives low.
- Add a configurable body inspection mode (body_detect_mode: observe/block/off,
  default observe) so the new deep checks record rather than block until an
  operator confirms them, plus body_detect_field_exclude to skip fields that
  legitimately carry rich text.
- Keep false positives down on the new paths: skip structured values, require a
  corroborating signal before flagging body/header XSS, and leave dual-use
  keywords out of the fallback lists.
- Path traversal is now normalized and judged on whether it escapes the site
  root instead of matching literally; this also clears a long-standing false
  positive on legitimate in-site relative paths. Adds a sensitive-file list.
- Scanner detection now covers all request headers and known probe paths.

Plugins:
- Suspend plugin loading pending signing and admission work. The code path is
  retained but gated off, and shipped disabled by default.

Validated against a local test corpus and a 33k real-traffic benchmark:
detection improved across every category while the real-traffic false-positive
count stayed flat.
2026-08-23 11:29:22 +08:00

66 lines
2.0 KiB
Go

package wafenginecore
import (
"net/http"
"testing"
)
func reqWithHeader(name, val string) *http.Request {
r, _ := http.NewRequest("GET", "http://x/", nil)
r.Header.Set(name, val)
return r
}
// S1-4:自定义头里的注入应被对应 check 命中
func TestHeaderDetect_Hits(t *testing.T) {
if !headerXSSHit(reqWithHeader("X-Custom", "<script>alert(1)</script>")) {
t.Error("头位 XSS 应命中")
}
if !headerSQLHit(reqWithHeader("X-Api", "1;exec sp_configure 'xp_cmdshell',1;reconfigure;--")) {
t.Error("头位 SQLi(关键字) 应命中")
}
if !headerSQLHit(reqWithHeader("X-Forwarded-Host", "1' or '1'='1")) {
t.Error("头位 SQLi(libinjection) 应命中")
}
if ok, _ := headerRCEHit(reqWithHeader("X-Cmd", "who^ami")); !ok {
t.Error("头位命令注入(反混淆) 应命中")
}
if ok, _ := headerRCEHit(reqWithHeader("X-Debug", ";id")); !ok {
t.Error("头位命令注入 应命中")
}
}
// 标准/浏览器头及正常自定义头不应误报
func TestHeaderDetect_NoFP(t *testing.T) {
r, _ := http.NewRequest("GET", "http://x/", nil)
r.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
r.Header.Set("Referer", "https://site.com/search?q=select+all&cat=news")
r.Header.Set("Accept", "text/html,application/xhtml+xml,*/*;q=0.8")
r.Header.Set("Sec-Ch-Ua", `"Chromium";v="120", "Not?A_Brand";v="8"`)
r.Header.Set("X-Requested-With", "XMLHttpRequest")
r.Header.Set("X-Custom-Id", "user-12345")
if headerXSSHit(r) {
t.Error("正常头不应判 XSS")
}
if headerSQLHit(r) {
t.Error("正常头不应判 SQLi")
}
if ok, _ := headerRCEHit(r); ok {
t.Error("正常头不应判命令注入")
}
}
func TestSkipDetectHeader(t *testing.T) {
skip := []string{"Host", "User-Agent", "Referer", "Accept", "Cookie", "Sec-Fetch-Site", "waf_req_uuid"}
for _, h := range skip {
if !skipDetectHeader(h) {
t.Errorf("应跳过标准头: %s", h)
}
}
for _, h := range []string{"X-Custom", "X-Forwarded-Host", "X-Cmd"} {
if skipDetectHeader(h) {
t.Errorf("自定义头不应跳过: %s", h)
}
}
}