Skip to content

hsluoyz/modsecurity-go

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This Project Is WIP.

This Project is work in progress. Api will be changed frequently. Not recommended for production use.

ModSecurity-Go

GoDoc CI Status Coverage Status codebeat badge License

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:

  • SecLang parser
  • Implement SecLang Processor
  • Implement SecLang Level 1(WIP)
  • Compatible with OWASP

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/hsluoyz/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