This Project Is WIP.
This Project is work in progress. Api will be changed frequently. Not recommended for production use.
ModSecurity-Go
ModSecurity-Go is golang port for ModSecurity.
Project is Working in progress.
The current goal is to implement ModSecurity Rules Language Porting Specification Level 1
TODO:
Usage
Build Rules with SecLang
For full example see Rules with SecLang Example
rule := `SecRuleEngine On
SecRule REQUEST_URI '@rx cmd' \
"id:123,\
phase:2,\
t:lowercase,\
deny"`
eng := modsecurity.NewEngine()
rs, err := seclang.NewRuleSetFromSecLangString(rule)
if err != nil {
panic(err)
}
err = rs.Execute(eng)
if err != nil {
panic(err)
}
ts, _ := eng.NewTransaction()
ts.ProcessConnection("127.0.0.1", "12345", "127.0.0.1", "80")
u, err := url.Parse(`/search?="a';CMD echo '1"`)
if err != nil {
panic(err)
}
ts.ProcessRequestURL(u, "GET", "HTTP/1.1")
ts.ProcessRequestHeader(nil)
i := ts.Result()
utils.Pprint(i)
// Output:
// (*modsecurity.Intervention)({
// Status: (int) 403,
// Pause: (time.Duration) 0s,
// Url: (*url.URL)(<nil>),
// Log: ([]string) (len=1 cap=1) {
// (string) (len=73) "[client 127.0.0.1:12345](phase 2)ModSecurity: Access denied with code 403"
// },
// Disruptive: (bool) true
// })
Build Rules with Go
For full example see Rules with Go Example
e := modsecurity.NewEngine()
// enable engine
e.Enable(modsecurity.StatusOn)
// make rule set
ruleSet := modsecurity.NewSecRuleSet()
// make rule
rule := &modsecurity.SecRule{
Phase: modsecurity.PhaseRequestHeaders,
}
// Variable: REQUEST_URI
rule.AppendVariables(modsecurity.NewVariableRequestURI())
// Operation: rx select
op, err := modsecurity.NewOperatorRx("select")
if err != nil {
panic(err)
}
rule.SetOperator(op)
// Action: deny
rule.AppendActions(modsecurity.NewActionDeny())
ruleSet.AddRules(rule)
// running rule
// make Transaction
ts, _ := modsecurity.NewTransaction(e, ruleSet)
// request header phase
ts.ProcessConnection("127.0.0.1", "12345", "127.0.0.1", "80")
u, err := url.Parse(`/search?="a';select '1"`)
if err != nil {
panic(err)
}
ts.ProcessRequestURL(u, "GET", "HTTP/1.1")
ts.ProcessRequestHeader(nil)
i := ts.Result()
pprint := spew.NewDefaultConfig()
pprint.DisablePointerAddresses = true
pprint.Dump(i)
// Output:
// (*modsecurity.Intervention)({
// Status: (int) 403,
// Pause: (time.Duration) 0s,
// Url: (*url.URL)(<nil>),
// Log: ([]string) (len=1 cap=1) {
// (string) (len=73) "[client 127.0.0.1:12345](phase 2)ModSecurity: Access denied with code 403"
// },
// Disruptive: (bool) true
// })
Seclang Parsing
For full example see Parser Example
import "github.com/senghoo/modsecurity-go/seclang/parser"
var rules = `<<<some modsecurity rules>>`
scaner := parser.NewSecLangScannerFromString(rules)
d, err := scaner.AllDirective()
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", d)
Supported Features
Directives
- SecRuleEngine
- SecRule
- SecRequestBodyAccess
- SecResponseBodyAccess
Variables
- ARGS
- ARGS_NAMES
- QUERY_STRING
- REMOTE_ADDR
- REQUEST_BASENAME
- REQUEST_BODY
- REQUEST_COOKIES
- REQUEST_COOKIES_NAMES
- REQUEST_FILENAME
- REQUEST_HEADERS
- REQUEST_HEADERS_NAMES
- REQUEST_METHOD
- REQUEST_PROTOCOL
- REQUEST_URI
- RESPONSE_BODY
- RESPONSE_CONTENT_LENGTH
- RESPONSE_CONTENT_TYPE
- RESPONSE_HEADERS
- RESPONSE_HEADERS_NAMES
- RESPONSE_PROTOCOL
- RESPONSE_STATUS
- XML
Operators
- rx
- eq
- ge
- gt
- le
- lt
Actions
- allow
- msg
- id
- rev
- ver
- severity
- log
- deny
- block
- status
- phase
- t
- skip
- chain
- logdata
- setvar
- capture
- pass
Transformation Functions
- lowercase
- urlDecode
- urlDecodeUni
- none
- compressWhitespace
- removeWhitespace
- replaceNulls
- removeNulls