Custom WAF Rules
Problem to solve
GitLab provides WAF with OWASP default rules. This provides a powerful set of out-of-the-box controls. However, some users will need to tune the configuration to fit the specific needs of their application's security requirements in order to tune the rules for false positives (blocking legitimate requests), false negatives (missed attacks), and performance impact (as WAF rules can introduce latency even if they don't detect an issue - example). This is especially relevant for those users who will be using the blocking mode of the WAF as false positives can break normal functionality of the application. Additionally, the WAF rules may need to be tuned over time as the applications protected by the WAF change.
Intended users
Further details
This is our users first opportunity to provide custom rules. This will be done in parallel with additional UX work to uncover & validate the long-term experience we want to provide around WAF rules. As such, we should focus on the minimal way to provide custom WAF rules in case we decide to go a different direction after discovery completes.
In context of this issue, custom rules means the SecRule objects that ModSecurity
is parsing.
Proposal
Provide a way for users to specify a set of custom rules that ModSecurity
should use for their project specifically.
- Allow users to specify a list of custom
ModSecurity
rules for apps deployed via AutoDevops pipeline -
Usage ping & GitLab.com reportingReport when a custom rule has been provided.- Usage reporting is not supported yet for CI-based installation/management of apps. see ~"devops::configure" #195428
- A GitLab Ultimate license is required to use this functionality
- A "wizard"-like experience to define WAF custom rules
Permissions and Security
What does success look like, and how can we measure that?
- At least 20% of WAF installations using customized rules, beyond the default Core Rule Set.
- This will measure if the capability is being adopted or not.
- First customized rule introduced within 30 days (median time) of enabling the WAF.
- This will measure if the problem custom rules solves is urgent enough to immediately adopt it and that customers are able to do so successfully.
Documentation
Documentation should cover:
- A description of what a WAF rule is
- A description of why a user would want to provide a custom WAF rule
- A description of the different things that can be part of a custom WAF rule
- An example of adding a custom rule
- Describe how to configure custom WAF rules for multiple projects in the same cluster.
- Describe how to configure custom WAF rules for multiple environments in the same project.
- Some possibly helpful discussion is here
Testing
Testing should cover:
- (If per-project rules are possible) Multiple applications hosted in the same Kubernetes cluster, each with a different set of rules
What is the type of buyer?
Custom rules require a GitLab Ultimate license.
Links / references
-
nginx.ingress.kubernetes.io/modsecurity-snippet
documentation for specifying WAF rules (https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#modsecurity)
Technical discovery
Custom SecRule definitions are already supported by the nginx ingress via nginx.ingress.kubernetes.io/modsecurity-snippet annotation on the ingress object. We already utilize this annotation in the auto-deploy helm charts. We can extend auto-deploy helm chart to allow installation of custom SecRule
definitions via AutoDevops pipelines.
AutoDevops installation script supports custom helm value injection from the .gitlab/auto-deploy-values.yaml. We can use this file as a source for custom SecRule
definitions, these values will be available to the auto-deploy helm chart.
Technical implementation details
Custom security rules has been tested on QA Stage. It consists of adding auto-deploy-values.yaml with a custom set of rules.
After deploying, those rules will be reflected into a ingress
resource as in:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine DetectionOnly
SecRule REQUEST_HEADERS:User-Agent \"scanner\" \"log,deny,id:107,status:403,msg:\'Scanner Identified\'\"
SecRule REQUEST_HEADERS:Content-Type \"text/plain\" \"log,deny,id:\'20010\',status:403,msg:\'Text plain not allowed\'\"
And triggering any of the custom rules will make their respective information to be logged:
{"transaction":{"client_ip":"10.7.0.1","time_stamp":"Tue Feb 11 17:55:48 2020","server_id":"2925010bf8ff7530fb12f428c8f50cfe9ed3cb54","client_port":63310,"host_ip":"10.7.0.1","host_port":443,"unique_id":"4458073-r
eview-add-custom-gseb0i.35.223.189.110.nip.io-10497db4ab4a525f6298a81aba3a26f7","request":{"method":"GET","http_version":2.0,"uri":"/","headers":{"host":"4458073-review-add-custom-gseb0i.35.223.189.110.nip.io","ac
cept":"*/*","user-agent":"scanner"}},"response":{"http_code":200,"headers":{"Server":"openresty/1.15.8.1","Date":"Tue, 11 Feb 2020 17:55:48 GMT","Content-Length":"533","Content-Type":"text/html; charset=utf-8","Co
nnection":"close","X-Powered-By":"Express","ETag":"W/\"215-6qyj89bEFIIR1ADo5la5A1TprZQ\"","Strict-Transport-Security":"max-age=15724800; includeSubDomains"}},"producer":{"modsecurity":"ModSecurity v3.0.3 (Linux)",
"connector":"ModSecurity-nginx v1.0.0","secrules_engine":"DetectionOnly","components":["OWASP_CRS/3.1.0\""]},"messages":[{"message":"Scanner Identified","details":{"match":"Matched \"Operator `Rx' with parameter `
scanner' against variable `REQUEST_HEADERS:user-agent' (Value: `scanner' )","reference":"o0,7v100,7","ruleId":"107","file":"<<reference missing or not informed>>","lineNumber":"3","data":"","severity":"0","ver":""
,"rev":"","tags":[],"maturity":"0","accuracy":"0"}}]}}
Documentation related to custom rules have been also merged and can be found at https://docs.gitlab.com/ee/topics/autodevops/#web-application-firewall-modsecurity-customization
Demo Project
WAF demo project has been updated to include one custom rule. It also serve as a basic testing of the feature in production enviroment.