mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-11-03 03:31:58 +08:00
Merge pull request #458 from samwafgo/feat_rule_headers
feat:add rule header
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package innerbean
|
||||
|
||||
import "strings"
|
||||
|
||||
type WebLog struct {
|
||||
WafInnerDFlag string `json:"waf_inner_dflag"` //日志队列处理方式
|
||||
HOST string `json:"host"`
|
||||
@@ -49,6 +51,46 @@ type WebLog struct {
|
||||
LogOnlyMode int `json:"log_only_mode"` //是否只记录日志 1 是 0 不是
|
||||
}
|
||||
|
||||
// GetHeaderValue 从HEADER字段中提取指定header的值
|
||||
// headerName: 要查找的header名称(不区分大小写)
|
||||
// 返回: header的值,如果不存在则返回空字符串
|
||||
func (w *WebLog) GetHeaderValue(headerName string) string {
|
||||
if w.HEADER == "" || headerName == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 将header名称转换为小写进行比较
|
||||
headerName = strings.ToLower(headerName)
|
||||
|
||||
// 按行分割header字符串
|
||||
lines := strings.Split(w.HEADER, "\r\n")
|
||||
|
||||
for _, line := range lines {
|
||||
// 跳过空行
|
||||
if strings.TrimSpace(line) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查找冒号分隔符
|
||||
colonIndex := strings.Index(line, ":")
|
||||
if colonIndex == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 提取header名称和值
|
||||
key := strings.ToLower(strings.TrimSpace(line[:colonIndex]))
|
||||
value := strings.TrimSpace(line[colonIndex+1:])
|
||||
|
||||
// 如果找到匹配的header,返回其值
|
||||
if key == headerName {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
// 未找到指定的header,返回空字符串
|
||||
return ""
|
||||
}
|
||||
|
||||
// 在 GORM 的 Model 方法中定义复合索引
|
||||
func (WebLog) TableName() string {
|
||||
return "web_logs"
|
||||
|
||||
@@ -59,6 +59,72 @@ rule R1ca0bf1c409e4c1b823c995afe7733b0 "禁止一些robotahrefs" salience 10 {
|
||||
|
||||
}
|
||||
|
||||
// TestWebLog_GetHeaderValue 测试WebLog的GetHeaderValue方法
|
||||
func TestWebLog_GetHeaderValue(t *testing.T) {
|
||||
//加载主机对于的规则
|
||||
ruleHelper := &RuleHelper{}
|
||||
ruleHelper.InitRuleEngine()
|
||||
|
||||
drls := `
|
||||
|
||||
rule R1ca0bf1c409e4c1b823c995afe7733b0 "判断header里面的组合信息" salience 10 {
|
||||
when
|
||||
MF.GetHeaderValue("Accept").Contains("text/plain") == True && MF.GetHeaderValue("X-Real-IP").Contains("10.0.0.1") == True
|
||||
then
|
||||
|
||||
Retract("R1ca0bf1c409e4c1b823c995afe7733b0");
|
||||
} `
|
||||
var ruleconfigs []model.Rules
|
||||
rule := model.Rules{
|
||||
HostCode: "",
|
||||
RuleCode: "",
|
||||
RuleName: "我是规则",
|
||||
RuleContent: drls,
|
||||
RuleContentJSON: "",
|
||||
RuleVersionName: "",
|
||||
RuleVersion: 0,
|
||||
IsPublicRule: 0,
|
||||
IsManualRule: 0,
|
||||
RuleStatus: 0,
|
||||
}
|
||||
ruleconfigs = append(ruleconfigs, rule)
|
||||
ruleHelper.LoadRules(ruleconfigs)
|
||||
|
||||
//weblog
|
||||
logs := innerbean.WebLog{
|
||||
USER_AGENT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)",
|
||||
HEADER: "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\r\n" +
|
||||
"Accept: application/json, text/plain, */*\r\n" +
|
||||
"Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n" +
|
||||
"Accept-Encoding: gzip, deflate, br\r\n" +
|
||||
"Content-Type: application/json\r\n" +
|
||||
"Content-Length: 123\r\n" +
|
||||
"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\r\n" +
|
||||
"X-Forwarded-For: 10.0.0.1, 192.168.1.1\r\n" +
|
||||
"X-Real-IP: 10.0.0.1\r\n" +
|
||||
"X-Custom-Header: custom-value-123\r\n" +
|
||||
"Cookie: session_id=abc123; user_pref=dark_mode\r\n" +
|
||||
"Referer: https://example.com/login\r\n" +
|
||||
"Origin: https://example.com\r\n" +
|
||||
"Connection: keep-alive\r\n" +
|
||||
"Cache-Control: no-cache\r\n",
|
||||
}
|
||||
ruleMatchs, err := ruleHelper.Match("MF", &logs)
|
||||
if err == nil {
|
||||
if len(ruleMatchs) > 0 {
|
||||
fmt.Printf("header里面的组合信息匹配成功,规则描述:%s\n", ruleMatchs[0].RuleDescription)
|
||||
rulestr := ""
|
||||
for _, v := range ruleMatchs {
|
||||
rulestr = rulestr + v.RuleDescription + ","
|
||||
}
|
||||
fmt.Printf("%s", rulestr)
|
||||
return
|
||||
} else {
|
||||
fmt.Printf("header里面的组合信息匹配失败\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAllRulesInDirectory 测试rule_tests目录下所有规则文件
|
||||
func TestAllRulesInDirectory(t *testing.T) {
|
||||
// 初始化规则引擎
|
||||
|
||||
Reference in New Issue
Block a user