Skip to content

Commit

Permalink
annotation to ignore given list of WAF rulesets (#2314)
Browse files Browse the repository at this point in the history
  • Loading branch information
ElvinEfendi authored and aledbf committed Apr 9, 2018
1 parent a6fe800 commit 16faf30
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 9 deletions.
10 changes: 10 additions & 0 deletions docs/user-guide/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ The following annotations are supported:
|[nginx.ingress.kubernetes.io/enable-access-log](#enable-access-log)|"true" or "false"|
|[nginx.ingress.kubernetes.io/lua-resty-waf](#lua-resty-waf)|"true" or "false"|
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|

**Note:** all the values must be a string. In case of booleans or number it must be quoted.

Expand Down Expand Up @@ -476,3 +477,12 @@ nginx.ingress.kubernetes.io/lua-resty-waf: "true"
```

In order to run it in debugging mode you can set `nginx.ingress.kubernetes.io/lua-resty-waf-debug` to `"true"` in addition to the above configuration.

`lua-resty-waf` comes with predefined set of rules(https://github.com/p0pr0ck5/lua-resty-waf/tree/84b4f40362500dd0cb98b9e71b5875cb1a40f1ad/rules) that covers ModSecurity CRS.
You can use `nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets` to ignore subset of those rulesets. For an example:

```yaml
nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets: "41000_sqli, 42000_xss"
```

will ignore the two mentioned rulesets.
2 changes: 1 addition & 1 deletion internal/file/bindata.go

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions internal/ingress/annotations/luarestywaf/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ limitations under the License.
package luarestywaf

import (
"reflect"
"strings"

extensions "k8s.io/api/extensions/v1beta1"

"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
Expand All @@ -25,8 +28,9 @@ import (

// Config returns lua-resty-waf configuration for an Ingress rule
type Config struct {
Enabled bool `json:"enabled"`
Debug bool `json:"debug"`
Enabled bool `json:"enabled"`
Debug bool `json:"debug"`
IgnoredRuleSets []string `json: "ignored-rulesets"`
}

// Equal tests for equality between two Config types
Expand All @@ -43,6 +47,9 @@ func (e1 *Config) Equal(e2 *Config) bool {
if e1.Debug != e2.Debug {
return false
}
if !reflect.DeepEqual(e1.IgnoredRuleSets, e2.IgnoredRuleSets) {
return false
}

return true
}
Expand All @@ -67,8 +74,15 @@ func (a luarestywaf) Parse(ing *extensions.Ingress) (interface{}, error) {

debug, _ := parser.GetBoolAnnotation("lua-resty-waf-debug", ing)

ignoredRuleSetsStr, _ := parser.GetStringAnnotation("lua-resty-waf-ignore-rulesets", ing)
ignoredRuleSets := strings.FieldsFunc(ignoredRuleSetsStr, func(c rune) bool {
strC := string(c)
return strC == "," || strC == " "
})

return &Config{
Enabled: enabled,
Debug: debug,
Enabled: enabled,
Debug: debug,
IgnoredRuleSets: ignoredRuleSets,
}, nil
}
15 changes: 11 additions & 4 deletions internal/ingress/annotations/luarestywaf/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
func TestParse(t *testing.T) {
luaRestyWAFAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf")
luaRestyWAFDebugAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-debug")
luaRestyWAFIgnoredRuleSetsAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-ignore-rulesets")

ap := NewParser(&resolver.Mock{})
if ap == nil {
Expand All @@ -42,12 +43,18 @@ func TestParse(t *testing.T) {
{nil, &Config{}},
{map[string]string{}, &Config{}},

{map[string]string{luaRestyWAFAnnotation: "true"}, &Config{Enabled: true, Debug: false}},
{map[string]string{luaRestyWAFAnnotation: "true"}, &Config{Enabled: true, Debug: false, IgnoredRuleSets: []string{}}},
{map[string]string{luaRestyWAFDebugAnnotation: "true"}, &Config{Enabled: false, Debug: false}},

{map[string]string{luaRestyWAFAnnotation: "true", luaRestyWAFDebugAnnotation: "true"}, &Config{Enabled: true, Debug: true}},
{map[string]string{luaRestyWAFAnnotation: "true", luaRestyWAFDebugAnnotation: "false"}, &Config{Enabled: true, Debug: false}},
{map[string]string{luaRestyWAFAnnotation: "false", luaRestyWAFDebugAnnotation: "true"}, &Config{Enabled: false, Debug: true}},
{map[string]string{luaRestyWAFAnnotation: "true", luaRestyWAFDebugAnnotation: "true"}, &Config{Enabled: true, Debug: true, IgnoredRuleSets: []string{}}},
{map[string]string{luaRestyWAFAnnotation: "true", luaRestyWAFDebugAnnotation: "false"}, &Config{Enabled: true, Debug: false, IgnoredRuleSets: []string{}}},
{map[string]string{luaRestyWAFAnnotation: "false", luaRestyWAFDebugAnnotation: "true"}, &Config{Enabled: false, Debug: true, IgnoredRuleSets: []string{}}},

{map[string]string{
luaRestyWAFAnnotation: "true",
luaRestyWAFDebugAnnotation: "true",
luaRestyWAFIgnoredRuleSetsAnnotation: "ruleset1, ruleset2 ruleset3, another.ruleset"},
&Config{Enabled: true, Debug: true, IgnoredRuleSets: []string{"ruleset1", "ruleset2", "ruleset3", "another.ruleset"}}},
}

ing := &extensions.Ingress{
Expand Down
4 changes: 4 additions & 0 deletions rootfs/etc/nginx/template/nginx.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,10 @@ stream {
waf:set_option("res_tid_header", true)
{{ end }}

{{ range $ruleset := $location.LuaRestyWAF.IgnoredRuleSets }}
waf:set_option("ignore_ruleset", "{{ $ruleset }}")
{{ end }}

waf:exec()
}
header_filter_by_lua_block {
Expand Down
15 changes: 15 additions & 0 deletions test/e2e/annotations/luarestywaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
Expect(len(errs)).Should(Equal(0))
Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))
})
It("should not apply ignored rulesets", func() {
host := "foo"
createIngress(f, host, map[string]string{
"nginx.ingress.kubernetes.io/lua-resty-waf": "true",
"nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets": "41000_sqli, 42000_xss"})

url := fmt.Sprintf("%s?msg=<A href=\"http://mysite.com/\">XSS</A>", f.NginxHTTPURL)
resp, _, errs := gorequest.New().
Get(url).
Set("Host", host).
End()

Expect(len(errs)).Should(Equal(0))
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
})
})

Context("when lua-resty-waf is not enabled", func() {
Expand Down

0 comments on commit 16faf30

Please sign in to comment.