Name log fields, metrics and the Core Rule Set package for what they are (closes #192)
check / check (push) Successful in 3m40s
check / check (push) Successful in 3m40s
Log field, metric, action and event names now say what they count and, for timings, the unit. Package internal/waf is internal/coreruleset. Model: opus-5-5
This commit is contained in:
1 parent
aede434f6a
commit
92ed102595
52 files changed
+654
-607
No files matched your search
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||
"sneak.berlin/go/smallwebwaf/internal/coreruleset"
|
||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||
"sneak.berlin/go/smallwebwaf/internal/waf"
|
||||
)
|
||||
|
||||
// coreRuleSet inspects the request with the Core Rule Set, unless
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// pathExempt decides, and notes the rules it matched and its score in the
|
||||
// log line, and the rules in the metrics. A score at or over
|
||||
// SWW_WAF_ANOMALY_THRESHOLD is a match: it adds the tag exploitsignature,
|
||||
// raises the waf_block alert, and in block mode refuses the request with 403,
|
||||
// raises the core_rule_set_match alert, and in block mode refuses the request with 403,
|
||||
// which is an offence its client's history counts. Its figures are the score
|
||||
// and the threshold.
|
||||
type coreRuleSet struct{}
|
||||
@@ -38,12 +38,12 @@ func (coreRuleSet) check(_ context.Context, rq *request, _ time.Time) *verdict {
|
||||
result, read, _ := rq.h.coreRuleSet.Inspect(rq.in, rq.client, rq.in.Body)
|
||||
rq.requestBytes = int64(len(read))
|
||||
|
||||
rq.line.DurationWAF = new(requestlog.Milliseconds(time.Since(start)))
|
||||
rq.line.WAFRuleIDs = result.RuleIDs
|
||||
rq.line.WAFScore = &result.Score
|
||||
rq.line.DurationCoreRuleSetMS = new(requestlog.Milliseconds(time.Since(start)))
|
||||
rq.line.CoreRuleSetRuleIDs = result.RuleIDs
|
||||
rq.line.CoreRuleSetScore = &result.Score
|
||||
|
||||
for _, id := range result.RuleIDs {
|
||||
rq.h.metrics.WAFMatched(cfg.WAFMode, id)
|
||||
rq.h.metrics.CoreRuleSetMatched(cfg.WAFMode, id)
|
||||
}
|
||||
|
||||
threshold := cfg.WAFAnomalyThreshold
|
||||
@@ -52,26 +52,26 @@ func (coreRuleSet) check(_ context.Context, rq *request, _ time.Time) *verdict {
|
||||
}
|
||||
|
||||
rq.addTag(config.ExploitSignatureTag)
|
||||
rq.alertWAFBlock(result)
|
||||
rq.alertCoreRuleSetMatch(result)
|
||||
|
||||
if cfg.WAFMode == config.WAFModeDetect {
|
||||
return nil
|
||||
}
|
||||
|
||||
rq.wafBlocked = true
|
||||
rq.blockedByCoreRuleSet = true
|
||||
|
||||
return &verdict{
|
||||
action: requestlog.ActionWAFBlocked,
|
||||
action: requestlog.ActionBlockedByCoreRuleSet,
|
||||
figures: map[string]any{figureScore: result.Score, "threshold": threshold},
|
||||
}
|
||||
}
|
||||
|
||||
// alertWAFBlock raises the waf_block alert for the request, which the Core
|
||||
// Rule Set scored at result, at or over SWW_WAF_ANOMALY_THRESHOLD. Its
|
||||
// alertCoreRuleSetMatch raises the core_rule_set_match alert for the request,
|
||||
// which the Core Rule Set scored at result, at or over SWW_WAF_ANOMALY_THRESHOLD. Its
|
||||
// detail gives the rule ids, the score, the method and the path with the
|
||||
// query, and, for a request that is not refused for it, the mode: detect,
|
||||
// or observe in observe mode.
|
||||
func (rq *request) alertWAFBlock(result waf.Result) {
|
||||
func (rq *request) alertCoreRuleSetMatch(result coreruleset.Result) {
|
||||
detail := map[string]any{
|
||||
"rule_ids": result.RuleIDs,
|
||||
"score": result.Score,
|
||||
@@ -87,7 +87,7 @@ func (rq *request) alertWAFBlock(result waf.Result) {
|
||||
}
|
||||
|
||||
rq.h.alerts.Raise(alerts.Alert{
|
||||
Event: alerts.EventWAFBlock,
|
||||
Event: alerts.EventCoreRuleSetMatch,
|
||||
Host: rq.site,
|
||||
Client: rq.client,
|
||||
Netblock: rq.h.clientGroup(rq.client),
|
||||
|
||||
Reference in new issue
Block a user