mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-11-01 18:51:45 +08:00
Merge pull request #636 from samwafgo/feat_cc_444
feat:custom page support attack_type / http code 444 disconnected con
This commit is contained in:
@@ -7,6 +7,7 @@ type BlockingPage struct {
|
||||
baseorm.BaseOrm
|
||||
BlockingPageName string `json:"blocking_page_name"` //自定义拦截模板页面名称
|
||||
BlockingType string `json:"blocking_type"` //自定义类型 被拦截
|
||||
AttackType string `json:"attack_type"` //攻击类型 如: cc_attack, sensitive_word, sql_injection等
|
||||
HostCode string `json:"host_code"` //适用于某个网站唯一码
|
||||
ResponseCode string `json:"response_code"` //响应代码 默认403
|
||||
ResponseHeader string `json:"response_header"` //响应Header头信息(JSON)
|
||||
|
||||
@@ -5,6 +5,7 @@ import "SamWaf/model/common/request"
|
||||
type WafBlockingPageAddReq struct {
|
||||
BlockingPageName string `json:"blocking_page_name" form:"blocking_page_name"`
|
||||
BlockingType string `json:"blocking_type" form:"blocking_type"`
|
||||
AttackType string `json:"attack_type" form:"attack_type"`
|
||||
HostCode string `json:"host_code" form:"host_code"`
|
||||
ResponseCode string `json:"response_code" form:"response_code"`
|
||||
ResponseHeader string `json:"response_header" form:"response_header"`
|
||||
@@ -14,6 +15,7 @@ type WafBlockingPageEditReq struct {
|
||||
Id string `json:"id"`
|
||||
BlockingPageName string `json:"blocking_page_name" form:"blocking_page_name"`
|
||||
BlockingType string `json:"blocking_type" form:"blocking_type"`
|
||||
AttackType string `json:"attack_type" form:"attack_type"`
|
||||
HostCode string `json:"host_code" form:"host_code"`
|
||||
ResponseCode string `json:"response_code" form:"response_code"`
|
||||
ResponseHeader string `json:"response_header" form:"response_header"`
|
||||
|
||||
@@ -27,6 +27,7 @@ func (receiver *WafBlockingPageService) AddApi(req request.WafBlockingPageAddReq
|
||||
|
||||
BlockingPageName: req.BlockingPageName,
|
||||
BlockingType: req.BlockingType,
|
||||
AttackType: req.AttackType,
|
||||
HostCode: req.HostCode,
|
||||
ResponseCode: req.ResponseCode,
|
||||
ResponseHeader: req.ResponseHeader,
|
||||
@@ -151,6 +152,7 @@ func (receiver *WafBlockingPageService) ModifyApi(req request.WafBlockingPageEdi
|
||||
|
||||
"BlockingPageName": req.BlockingPageName,
|
||||
"BlockingType": req.BlockingType,
|
||||
"AttackType": req.AttackType,
|
||||
"HostCode": req.HostCode,
|
||||
"ResponseCode": req.ResponseCode,
|
||||
"ResponseHeader": req.ResponseHeader,
|
||||
|
||||
@@ -341,6 +341,34 @@ func RunCoreDBMigrations(db *gorm.DB) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
// 迁移9: 为 blocking_page 表添加 attack_type 字段(攻击类型)
|
||||
{
|
||||
ID: "202601090001_add_blocking_page_attack_type",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
zlog.Info("迁移 202601090001: 为 blocking_page 表添加 attack_type 字段")
|
||||
|
||||
// 检查字段是否已存在
|
||||
if tx.Migrator().HasColumn(&model.BlockingPage{}, "attack_type") {
|
||||
zlog.Info("attack_type 字段已存在,跳过添加")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 添加字段,默认值为空字符串(表示通用拦截页面)
|
||||
if err := tx.Migrator().AddColumn(&model.BlockingPage{}, "attack_type"); err != nil {
|
||||
return fmt.Errorf("添加 attack_type 字段失败: %w", err)
|
||||
}
|
||||
|
||||
zlog.Info("attack_type 字段添加成功")
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
zlog.Info("回滚 202601090001: 删除 blocking_page 表的 attack_type 字段")
|
||||
if tx.Migrator().HasColumn(&model.BlockingPage{}, "attack_type") {
|
||||
return tx.Migrator().DropColumn(&model.BlockingPage{}, "attack_type")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 执行迁移
|
||||
|
||||
+157
-79
@@ -4,6 +4,7 @@ import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/global"
|
||||
"SamWaf/innerbean"
|
||||
"SamWaf/model"
|
||||
"SamWaf/model/wafenginmodel"
|
||||
"SamWaf/utils"
|
||||
"bytes"
|
||||
@@ -32,8 +33,8 @@ func renderTemplate(templateContent string, data map[string]interface{}) ([]byte
|
||||
return renderedCode.Bytes(), nil
|
||||
}
|
||||
|
||||
// EchoErrorInfo ruleName 对内记录 blockInfo 对外展示
|
||||
func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean *innerbean.WebLog, ruleName string, blockInfo string, hostsafe *wafenginmodel.HostSafe, globalHostSafe *wafenginmodel.HostSafe, isLog bool) {
|
||||
// EchoErrorInfo ruleName 对内记录 blockInfo 对外展示 attackType 攻击类型
|
||||
func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean *innerbean.WebLog, ruleName string, blockInfo string, hostsafe *wafenginmodel.HostSafe, globalHostSafe *wafenginmodel.HostSafe, isLog bool, attackType string) {
|
||||
resBytes := []byte("")
|
||||
var responseCode int = 403
|
||||
|
||||
@@ -42,9 +43,41 @@ func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean *innerbean
|
||||
"SAMWAF_BLOCK_INFO": blockInfo,
|
||||
}
|
||||
|
||||
// 处理 hostsafe 的模板
|
||||
// response_code 为 403 的配置
|
||||
blockingPage, ok := hostsafe.BlockingPage["403"]
|
||||
// 优先根据攻击类型查找对应的拦截页面
|
||||
var blockingPage model.BlockingPage
|
||||
var ok bool
|
||||
|
||||
// 1. 优先查找网站级别的攻击类型专属拦截页面
|
||||
if attackType != "" {
|
||||
for _, page := range hostsafe.BlockingPage {
|
||||
if page.AttackType == attackType {
|
||||
blockingPage = page
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没找到攻击类型专属页面,尝试使用响应码为403的通用拦截页面
|
||||
if !ok {
|
||||
blockingPage, ok = hostsafe.BlockingPage["403"]
|
||||
}
|
||||
|
||||
// 3. 如果网站级别没找到,查找全局级别的攻击类型专属页面
|
||||
if !ok && attackType != "" {
|
||||
for _, page := range globalHostSafe.BlockingPage {
|
||||
if page.AttackType == attackType {
|
||||
blockingPage = page
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 如果还没找到,使用全局的403拦截页面
|
||||
if !ok {
|
||||
blockingPage, ok = globalHostSafe.BlockingPage["403"]
|
||||
}
|
||||
|
||||
if ok {
|
||||
// 设置 HTTP header
|
||||
@@ -72,42 +105,50 @@ func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean *innerbean
|
||||
responseCode = code
|
||||
}
|
||||
} else {
|
||||
// 检查全局配置
|
||||
globalBlockingPage, ok := globalHostSafe.BlockingPage["403"]
|
||||
if ok {
|
||||
// 处理 globalHostSafe 的模板
|
||||
// 设置 HTTP header
|
||||
var headers []map[string]string
|
||||
if err := json.Unmarshal([]byte(globalBlockingPage.ResponseHeader), &headers); err == nil {
|
||||
for _, header := range headers {
|
||||
if name, ok := header["name"]; ok {
|
||||
if value, ok := header["value"]; ok && value != "" {
|
||||
w.Header().Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
renderedBytes, err := renderTemplate(globalBlockingPage.ResponseContent, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(globalBlockingPage.ResponseContent)
|
||||
}
|
||||
// 设置响应码
|
||||
if code, err := strconv.Atoi(globalBlockingPage.ResponseCode); err == nil {
|
||||
responseCode = code
|
||||
}
|
||||
// 默认的阻止页面
|
||||
renderedBytes, err := renderTemplate(global.GLOBAL_DEFAULT_BLOCK_INFO, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
// 默认的阻止页面
|
||||
renderedBytes, err := renderTemplate(global.GLOBAL_DEFAULT_BLOCK_INFO, renderData)
|
||||
resBytes = []byte(global.GLOBAL_DEFAULT_BLOCK_INFO)
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊处理444状态码:直接关闭连接,不返回任何内容
|
||||
if responseCode == 444 {
|
||||
// 444状态码表示关闭连接,不返回任何响应
|
||||
if hj, ok := w.(http.Hijacker); ok {
|
||||
conn, _, err := hj.Hijack()
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(global.GLOBAL_DEFAULT_BLOCK_INFO)
|
||||
conn.Close()
|
||||
// 记录日志
|
||||
if isLog {
|
||||
go func() {
|
||||
// 发送推送消息
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.RuleMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "命中保护规则", Server: global.GWAF_CUSTOM_SERVER_NAME},
|
||||
Domain: weblogbean.HOST,
|
||||
RuleInfo: ruleName,
|
||||
Ip: fmt.Sprintf("%s (%s)", weblogbean.SRC_IP, utils.GetCountry(weblogbean.SRC_IP)),
|
||||
})
|
||||
}()
|
||||
|
||||
datetimeNow := time.Now()
|
||||
weblogbean.TimeSpent = datetimeNow.UnixNano()/1e6 - weblogbean.UNIX_ADD_TIME
|
||||
weblogbean.RES_BODY = "444 Connection Closed"
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "连接关闭"
|
||||
weblogbean.STATUS_CODE = 444
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
// 如果无法劫持连接,则降级为正常的403响应
|
||||
responseCode = 403
|
||||
}
|
||||
|
||||
w.WriteHeader(responseCode)
|
||||
@@ -135,15 +176,15 @@ func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean *innerbean
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "阻止访问"
|
||||
weblogbean.STATUS_CODE = 403
|
||||
weblogbean.STATUS_CODE = responseCode
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
}
|
||||
}
|
||||
|
||||
// EchoResponseErrorInfo ruleName 对内记录 blockInfo 对外展示
|
||||
func EchoResponseErrorInfo(resp *http.Response, weblogbean *innerbean.WebLog, ruleName string, blockInfo string, hostsafe *wafenginmodel.HostSafe, globalHostSafe *wafenginmodel.HostSafe, isLog bool) {
|
||||
// EchoResponseErrorInfo ruleName 对内记录 blockInfo 对外展示 attackType 攻击类型
|
||||
func EchoResponseErrorInfo(resp *http.Response, weblogbean *innerbean.WebLog, ruleName string, blockInfo string, hostsafe *wafenginmodel.HostSafe, globalHostSafe *wafenginmodel.HostSafe, isLog bool, attackType string) {
|
||||
resBytes := []byte("")
|
||||
var responseCode int = 403
|
||||
|
||||
@@ -152,9 +193,41 @@ func EchoResponseErrorInfo(resp *http.Response, weblogbean *innerbean.WebLog, ru
|
||||
"SAMWAF_BLOCK_INFO": blockInfo,
|
||||
}
|
||||
|
||||
// 处理 hostsafe 的模板
|
||||
// 优先使用 response_code 为 403 的配置,兼容旧版本的 other_block
|
||||
blockingPage, ok := hostsafe.BlockingPage["403"]
|
||||
// 优先根据攻击类型查找对应的拦截页面
|
||||
var blockingPage model.BlockingPage
|
||||
var ok bool
|
||||
|
||||
// 1. 优先查找网站级别的攻击类型专属拦截页面
|
||||
if attackType != "" {
|
||||
for _, page := range hostsafe.BlockingPage {
|
||||
if page.AttackType == attackType {
|
||||
blockingPage = page
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没找到攻击类型专属页面,尝试使用响应码为403的通用拦截页面
|
||||
if !ok {
|
||||
blockingPage, ok = hostsafe.BlockingPage["403"]
|
||||
}
|
||||
|
||||
// 3. 如果网站级别没找到,查找全局级别的攻击类型专属页面
|
||||
if !ok && attackType != "" {
|
||||
for _, page := range globalHostSafe.BlockingPage {
|
||||
if page.AttackType == attackType {
|
||||
blockingPage = page
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 如果还没找到,使用全局的403拦截页面
|
||||
if !ok {
|
||||
blockingPage, ok = globalHostSafe.BlockingPage["403"]
|
||||
}
|
||||
|
||||
if ok {
|
||||
// 设置 HTTP header
|
||||
@@ -182,45 +255,50 @@ func EchoResponseErrorInfo(resp *http.Response, weblogbean *innerbean.WebLog, ru
|
||||
responseCode = code
|
||||
}
|
||||
} else {
|
||||
// 检查全局配置
|
||||
globalBlockingPage, ok := globalHostSafe.BlockingPage["403"]
|
||||
|
||||
if ok {
|
||||
// 处理 globalHostSafe 的模板
|
||||
// 设置 HTTP header
|
||||
var headers []map[string]string
|
||||
if err := json.Unmarshal([]byte(globalBlockingPage.ResponseHeader), &headers); err == nil {
|
||||
for _, header := range headers {
|
||||
if name, ok := header["name"]; ok {
|
||||
if value, ok := header["value"]; ok && value != "" {
|
||||
resp.Header.Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
renderedBytes, err := renderTemplate(globalBlockingPage.ResponseContent, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(globalBlockingPage.ResponseContent)
|
||||
}
|
||||
// 设置响应码
|
||||
if code, err := strconv.Atoi(globalBlockingPage.ResponseCode); err == nil {
|
||||
responseCode = code
|
||||
}
|
||||
// 默认的阻止页面
|
||||
renderedBytes, err := renderTemplate(global.GLOBAL_DEFAULT_BLOCK_INFO, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
// 默认的阻止页面
|
||||
renderedBytes, err := renderTemplate(global.GLOBAL_DEFAULT_BLOCK_INFO, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(global.GLOBAL_DEFAULT_BLOCK_INFO)
|
||||
}
|
||||
resBytes = []byte(global.GLOBAL_DEFAULT_BLOCK_INFO)
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊处理444状态码:直接关闭连接
|
||||
if responseCode == 444 {
|
||||
// 444状态码表示关闭连接,设置空body
|
||||
resp.StatusCode = 444
|
||||
resp.Status = "444 Connection Closed Without Response"
|
||||
resp.Body = io.NopCloser(bytes.NewBuffer([]byte{}))
|
||||
resp.ContentLength = 0
|
||||
resp.Header.Set("Content-Length", "0")
|
||||
// 不设置Content-Type,让连接直接关闭
|
||||
|
||||
if isLog {
|
||||
go func() {
|
||||
// 发送推送消息
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.RuleMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "命中保护规则", Server: global.GWAF_CUSTOM_SERVER_NAME},
|
||||
Domain: weblogbean.HOST,
|
||||
RuleInfo: ruleName,
|
||||
Ip: fmt.Sprintf("%s (%s)", weblogbean.SRC_IP, utils.GetCountry(weblogbean.SRC_IP)),
|
||||
})
|
||||
}()
|
||||
|
||||
datetimeNow := time.Now()
|
||||
weblogbean.TimeSpent = datetimeNow.UnixNano()/1e6 - weblogbean.UNIX_ADD_TIME
|
||||
weblogbean.RES_BODY = "444 Connection Closed"
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "连接关闭"
|
||||
weblogbean.STATUS_CODE = 444
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
resp.StatusCode = responseCode
|
||||
|
||||
resp.Body = io.NopCloser(bytes.NewBuffer(resBytes))
|
||||
@@ -247,7 +325,7 @@ func EchoResponseErrorInfo(resp *http.Response, weblogbean *innerbean.WebLog, ru
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "阻止访问"
|
||||
weblogbean.STATUS_CODE = 403
|
||||
weblogbean.STATUS_CODE = responseCode
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
|
||||
@@ -77,6 +77,84 @@ func (waf *WafEngine) Error() string {
|
||||
zlog.Error(fmt.Sprintf(fs))
|
||||
return fmt.Sprintf(fs)
|
||||
}
|
||||
|
||||
// inferAttackType 根据检测规则标题推断攻击类型
|
||||
func inferAttackType(ruleTitle string) string {
|
||||
ruleTitle = strings.ToLower(ruleTitle)
|
||||
|
||||
// CC攻击
|
||||
if strings.Contains(ruleTitle, "cc") || strings.Contains(ruleTitle, "频次") || strings.Contains(ruleTitle, "rate limit") {
|
||||
return "cc_attack"
|
||||
}
|
||||
|
||||
// SQL注入
|
||||
if strings.Contains(ruleTitle, "sql") || strings.Contains(ruleTitle, "注入") {
|
||||
return "sql_injection"
|
||||
}
|
||||
|
||||
// XSS攻击
|
||||
if strings.Contains(ruleTitle, "xss") || strings.Contains(ruleTitle, "跨站") {
|
||||
return "xss_attack"
|
||||
}
|
||||
|
||||
// 扫描工具
|
||||
if strings.Contains(ruleTitle, "scan") || strings.Contains(ruleTitle, "扫描") {
|
||||
return "scan_tool"
|
||||
}
|
||||
|
||||
// RCE远程代码执行
|
||||
if strings.Contains(ruleTitle, "rce") || strings.Contains(ruleTitle, "代码执行") || strings.Contains(ruleTitle, "命令执行") {
|
||||
return "rce_attack"
|
||||
}
|
||||
|
||||
// 目录穿越
|
||||
if strings.Contains(ruleTitle, "traversal") || strings.Contains(ruleTitle, "穿越") || strings.Contains(ruleTitle, "目录") {
|
||||
return "dir_traversal"
|
||||
}
|
||||
|
||||
// Bot爬虫
|
||||
if strings.Contains(ruleTitle, "bot") || strings.Contains(ruleTitle, "爬虫") {
|
||||
return "bot_attack"
|
||||
}
|
||||
|
||||
// 敏感词
|
||||
if strings.Contains(ruleTitle, "sensitive") || strings.Contains(ruleTitle, "敏感词") {
|
||||
return "sensitive_word"
|
||||
}
|
||||
|
||||
// IP黑名单
|
||||
if strings.Contains(ruleTitle, "ip") && (strings.Contains(ruleTitle, "黑名单") || strings.Contains(ruleTitle, "block") || strings.Contains(ruleTitle, "deny")) {
|
||||
return "ip_blocked"
|
||||
}
|
||||
|
||||
// URL黑名单
|
||||
if strings.Contains(ruleTitle, "url") && (strings.Contains(ruleTitle, "黑名单") || strings.Contains(ruleTitle, "block") || strings.Contains(ruleTitle, "deny")) {
|
||||
return "url_blocked"
|
||||
}
|
||||
|
||||
// 防盗链
|
||||
if strings.Contains(ruleTitle, "leech") || strings.Contains(ruleTitle, "防盗链") || strings.Contains(ruleTitle, "hotlink") {
|
||||
return "anti_leech"
|
||||
}
|
||||
|
||||
// 自定义规则
|
||||
if strings.Contains(ruleTitle, "rule") || strings.Contains(ruleTitle, "规则") {
|
||||
return "custom_rule"
|
||||
}
|
||||
|
||||
// OWASP规则
|
||||
if strings.Contains(ruleTitle, "owasp") {
|
||||
return "owasp_rule"
|
||||
}
|
||||
|
||||
// 插件拦截
|
||||
if strings.Contains(ruleTitle, "plugin") || strings.Contains(ruleTitle, "插件") {
|
||||
return "plugin_block"
|
||||
}
|
||||
|
||||
// 默认返回通用拦截类型
|
||||
return ""
|
||||
}
|
||||
func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
innerLogName := "WafEngine ServeHTTP"
|
||||
global.IncrementQPS() // 使用统一的QPS增量函数
|
||||
@@ -358,7 +436,7 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
Duration: 0, // CC封禁时长由配置决定
|
||||
Time: time.Now().Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
EchoErrorInfo(w, r, &weblogbean, "", "当前IP由于访问频次太高暂时无法访问", hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], false)
|
||||
EchoErrorInfo(w, r, &weblogbean, "", "当前IP由于访问频次太高暂时无法访问", hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], false, "cc_attack")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -398,7 +476,9 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return false
|
||||
} else {
|
||||
decrementMonitor(hostCode)
|
||||
EchoErrorInfo(w, r, &weblogbean, detectionResult.Title, detectionResult.Content, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
// 根据检测结果的标题推断攻击类型
|
||||
attackType := inferAttackType(detectionResult.Title)
|
||||
EchoErrorInfo(w, r, &weblogbean, detectionResult.Title, detectionResult.Content, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true, attackType)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1025,7 +1105,7 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
|
||||
weblogfrist.RULE = "敏感词检测:" + string(matchBodyResult[0].Word)
|
||||
|
||||
} else {
|
||||
EchoResponseErrorInfo(resp, weblogfrist, "敏感词检测:"+string(matchBodyResult[0].Word), "敏感词内容", waf.HostTarget[host], waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
EchoResponseErrorInfo(resp, weblogfrist, "敏感词检测:"+string(matchBodyResult[0].Word), "敏感词内容", waf.HostTarget[host], waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true, "sensitive_word")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user