-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
105 lines (87 loc) · 3.06 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"embed"
"fmt"
"github.com/Kong/go-pdk"
"github.com/Kong/go-pdk/server"
"github.com/corazawaf/coraza/v3"
"log"
)
// region variables
//go:embed coraza.conf crs-setup.conf rules
var embedFS embed.FS
var wafMap = make(map[Config]coraza.WAF)
//var wafLock sync.Mutex
const (
PluginName = "Kong WAF"
Version = "0.0.1"
Priority = 909 // less than rate-limiting plugin(910)
corazaConf = "coraza.conf"
crsConf = "crs-setup.conf"
coreRules = "rules/*.conf"
// base rules need to be included when EnableAll in Config is false
csrInitRule = "rules/REQUEST-901-INITIALIZATION.conf"
blockingEvaluationRule = "rules/REQUEST-949-BLOCKING-EVALUATION.conf"
correlationRules = "rules/RESPONSE-980-CORRELATION.conf"
// protection strategy
scannerDetectionRules = "rules/REQUEST-913-SCANNER-DETECTION.conf"
multipartRules = "rules/REQUEST-922-MULTIPART-ATTACK.conf"
rceRules = "rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"
phpRules = "rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf"
genericRules = "rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf"
xssRules = "rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"
sqlInjectionRules = "rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"
sessionFixationRules = "rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf"
javaRules = "rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf"
webShellRules = "rules/RESPONSE-955-WEB-SHELLS.conf"
)
//endregion variables
func New() interface{} {
//todo: initialize config with some default value
config := &Config{}
return config
}
func main() {
err := server.StartServer(New, Version, Priority)
if err != nil {
log.Fatalf("Failed to start %s plugin", PluginName)
}
}
func (conf Config) Access(kong *pdk.PDK) {
//wafLock.Lock()
//defer wafLock.Unlock()
// get waf instance base on Config struct
_, exist := wafMap[conf]
if exist {
kong.Log.Debug(fmt.Printf("WAF instance with config %v exist - Not create again \n", conf))
} else {
wafInstance, err := createWaf(conf, kong)
if err != nil {
kong.Log.Err("Error while creating kong WAF instance \n", err)
panic(err)
}
wafMap[conf] = wafInstance
kong.Log.Debug(fmt.Sprintf("Create WAF instance created with config %v \n", conf))
}
waf := wafMap[conf]
// transaction handling
tx := waf.NewTransaction()
defer func() {
tx.ProcessLogging()
tx.Close()
}()
interruption, requestErr := processRequest(tx, kong)
transactionId := tx.ID()
tx.AddRequestHeader("X-Kong-WAF-Request-Id", transactionId)
kong.Response.SetHeader("X-Kong-WAF-Request-Id", transactionId)
if requestErr != nil {
kong.Response.ExitStatus(403)
kong.Response.Exit(403, []byte("Error in WAF, check your security rules."), nil)
}
if interruption != nil {
interruptionType := interruption.Action
interruptionId := interruption.RuleID
response := fmt.Sprintf("Request terminated by WAF - Action: %s - RuleId: %d - TransactionId: %s", interruptionType, interruptionId, transactionId)
kong.Response.Exit(403, []byte(response), nil)
}
}