2025-02-13 17:13:39 +05:30
|
|
|
package waf
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
_ "embed"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"log"
|
|
|
|
|
"regexp"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type WafDetector struct {
|
|
|
|
|
wafs map[string]waf
|
|
|
|
|
regexCache map[string]*regexp.Regexp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// waf represents a web application firewall definition
|
|
|
|
|
type waf struct {
|
|
|
|
|
Company string `json:"company"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
Regex string `json:"regex"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// wafData represents the root JSON structure
|
|
|
|
|
type wafData struct {
|
|
|
|
|
WAFs map[string]waf `json:"wafs"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:embed regexes.json
|
|
|
|
|
var wafContentRegexes string
|
|
|
|
|
|
|
|
|
|
func NewWafDetector() *WafDetector {
|
|
|
|
|
var data wafData
|
|
|
|
|
if err := json.Unmarshal([]byte(wafContentRegexes), &data); err != nil {
|
|
|
|
|
log.Printf("could not unmarshal waf content regexes: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
store := &WafDetector{
|
|
|
|
|
wafs: data.WAFs,
|
|
|
|
|
regexCache: make(map[string]*regexp.Regexp),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for id, waf := range store.wafs {
|
|
|
|
|
if waf.Regex == "" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2025-02-13 18:46:28 +05:30
|
|
|
compiled, err := regexp.Compile(waf.Regex)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("invalid WAF regex for %s: %v", id, err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
store.regexCache[id] = compiled
|
2025-02-13 17:13:39 +05:30
|
|
|
}
|
|
|
|
|
return store
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *WafDetector) DetectWAF(content string) (string, bool) {
|
2025-08-04 21:12:43 +05:30
|
|
|
if d == nil || d.regexCache == nil {
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-13 17:13:39 +05:30
|
|
|
for id, regex := range d.regexCache {
|
2025-08-04 21:12:43 +05:30
|
|
|
if regex != nil && regex.MatchString(content) {
|
2025-02-13 17:13:39 +05:30
|
|
|
return id, true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *WafDetector) GetWAF(id string) (waf, bool) {
|
|
|
|
|
waf, ok := d.wafs[id]
|
|
|
|
|
return waf, ok
|
|
|
|
|
}
|