minor waf fixes (#2693)
This commit is contained in:
parent
a504113186
commit
1c03fbe99e
5 changed files with 33 additions and 12 deletions
|
@ -335,7 +335,7 @@ func (w *AppsecSource) appsecHandler(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// parse the request only once
|
||||
parsedRequest, err := appsec.NewParsedRequestFromRequest(r)
|
||||
parsedRequest, err := appsec.NewParsedRequestFromRequest(r, w.logger)
|
||||
if err != nil {
|
||||
w.logger.Errorf("%s", err)
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
|
@ -28,6 +28,7 @@ rules:
|
|||
type match struct {
|
||||
Type string `yaml:"type"`
|
||||
Value string `yaml:"value"`
|
||||
Not bool `yaml:"not,omitempty"`
|
||||
}
|
||||
|
||||
type CustomRule struct {
|
||||
|
@ -40,7 +41,8 @@ type CustomRule struct {
|
|||
Transform []string `yaml:"transform"` //t:lowercase, t:uppercase, etc
|
||||
And []CustomRule `yaml:"and,omitempty"`
|
||||
Or []CustomRule `yaml:"or,omitempty"`
|
||||
BodyType string `yaml:"body_type,omitempty"`
|
||||
|
||||
BodyType string `yaml:"body_type,omitempty"`
|
||||
}
|
||||
|
||||
func (v *CustomRule) Convert(ruleType string, appsecRuleName string) (string, []uint32, error) {
|
||||
|
|
|
@ -18,6 +18,22 @@ func TestVPatchRuleString(t *testing.T) {
|
|||
},
|
||||
expected: `SecRule ARGS_GET:foo "@rx [^a-zA-Z]" "id:2203944045,phase:2,deny,log,msg:'Base Rule',tag:'crowdsec-Base Rule',t:lowercase"`,
|
||||
},
|
||||
{
|
||||
name: "Base Rule #2",
|
||||
rule: CustomRule{
|
||||
Zones: []string{"METHOD"},
|
||||
Match: match{Type: "startsWith", Value: "toto"},
|
||||
},
|
||||
expected: `SecRule REQUEST_METHOD "@beginsWith toto" "id:2759779019,phase:2,deny,log,msg:'Base Rule #2',tag:'crowdsec-Base Rule #2'"`,
|
||||
},
|
||||
{
|
||||
name: "Base Negative Rule",
|
||||
rule: CustomRule{
|
||||
Zones: []string{"METHOD"},
|
||||
Match: match{Type: "startsWith", Value: "toto", Not: true},
|
||||
},
|
||||
expected: `SecRule REQUEST_METHOD "!@beginsWith toto" "id:3966251995,phase:2,deny,log,msg:'Base Negative Rule',tag:'crowdsec-Base Negative Rule'"`,
|
||||
},
|
||||
{
|
||||
name: "Multiple Zones",
|
||||
rule: CustomRule{
|
||||
|
|
|
@ -44,6 +44,7 @@ var matchMap map[string]string = map[string]string{
|
|||
"lt": "@lt",
|
||||
"gte": "@ge",
|
||||
"lte": "@le",
|
||||
"eq": "@eq",
|
||||
}
|
||||
|
||||
var bodyTypeMatch map[string]string = map[string]string{
|
||||
|
@ -141,7 +142,11 @@ func (m *ModsecurityRule) buildRules(rule *CustomRule, appsecRuleName string, an
|
|||
|
||||
if rule.Match.Type != "" {
|
||||
if match, ok := matchMap[rule.Match.Type]; ok {
|
||||
r.WriteString(fmt.Sprintf(`"%s %s"`, match, rule.Match.Value))
|
||||
prefix := ""
|
||||
if rule.Match.Not {
|
||||
prefix = "!"
|
||||
}
|
||||
r.WriteString(fmt.Sprintf(`"%s%s %s"`, prefix, match, rule.Match.Value))
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown match type '%s'", rule.Match.Type)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -267,7 +268,7 @@ func (r *ReqDumpFilter) ToJSON() error {
|
|||
}
|
||||
|
||||
// Generate a ParsedRequest from a http.Request. ParsedRequest can be consumed by the App security Engine
|
||||
func NewParsedRequestFromRequest(r *http.Request) (ParsedRequest, error) {
|
||||
func NewParsedRequestFromRequest(r *http.Request, logger *logrus.Entry) (ParsedRequest, error) {
|
||||
var err error
|
||||
contentLength := r.ContentLength
|
||||
if contentLength < 0 {
|
||||
|
@ -282,26 +283,23 @@ func NewParsedRequestFromRequest(r *http.Request) (ParsedRequest, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// the real source of the request is set in 'x-client-ip'
|
||||
clientIP := r.Header.Get(IPHeaderName)
|
||||
if clientIP == "" {
|
||||
return ParsedRequest{}, fmt.Errorf("missing '%s' header", IPHeaderName)
|
||||
}
|
||||
// the real target Host of the request is set in 'x-client-host'
|
||||
clientHost := r.Header.Get(HostHeaderName)
|
||||
if clientHost == "" {
|
||||
return ParsedRequest{}, fmt.Errorf("missing '%s' header", HostHeaderName)
|
||||
}
|
||||
// the real URI of the request is set in 'x-client-uri'
|
||||
|
||||
clientURI := r.Header.Get(URIHeaderName)
|
||||
if clientURI == "" {
|
||||
return ParsedRequest{}, fmt.Errorf("missing '%s' header", URIHeaderName)
|
||||
}
|
||||
// the real VERB of the request is set in 'x-client-uri'
|
||||
clientMethod := r.Header.Get(VerbHeaderName)
|
||||
if clientMethod == "" {
|
||||
return ParsedRequest{}, fmt.Errorf("missing '%s' header", VerbHeaderName)
|
||||
}
|
||||
clientHost := r.Header.Get(HostHeaderName)
|
||||
if clientHost == "" { //this might be empty
|
||||
logger.Debugf("missing '%s' header", HostHeaderName)
|
||||
}
|
||||
|
||||
// delete those headers before coraza process the request
|
||||
delete(r.Header, IPHeaderName)
|
||||
|
|
Loading…
Reference in a new issue