Just started dabbling in running Kong with ModSecurity v3 with the Nginx connector and the OWASP CRS3. Figured I would throw together some snippets of code that may help folks out that want to play around with WAF embedded in their own Kong deployments.
First, the code. Note I am building via a docker file with base image Alpine, running Kong 1.4.3 right now.
Some dependencies you may need(not all relate to the WAF but 3-4 of these do).
RUN apk add --no-cache --virtual build-deps wget tar ca-certificates \
&& apk add --update --no-cache readline-dev outils-md5 linux-headers bsd-compat-headers m4 \
yaml-dev build-deps bash patch bash-completion automake bash-doc make gcc g++ libgcc zlib-dev curl curl-dev autoconf libtool perl pcre libxml2 libxml2-dev libmaxminddb-dev yajl yajl-dev pcre-dev unzip tzdata wrk luarocks git
Then the building of libs and some basic settings/files:
######------ ModSec NGINX WAF ------######
RUN git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity \
&& chmod -R 777 /ModSecurity \
&& cd ModSecurity \
&& git submodule init \
&& git submodule update \
&& ./build.sh \
&& ./configure \
&& make \
&& make install \
&& mv /ModSecurity/modsecurity.conf-recommended /ModSecurity/modsecurity.conf
# ^^^ Rename the conf file to be proper ^^^
#Return to ROOT DIR
RUN cd /
#NGINX ModSec v3 connector dynamic module
RUN git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git \
&& chmod -R 777 /ModSecurity-nginx
#OWASP CORE RULE SET, PARANOIA LEVEL 2
RUN wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.2.0.tar.gz \
&& tar -xzvf v3.2.0.tar.gz \
&& mv owasp-modsecurity-crs-3.2.0 /usr/local \
&& mv /usr/local/owasp-modsecurity-crs-3.2.0/crs-setup.conf.example /usr/local/owasp-modsecurity-crs-3.2.0/crs-setup.conf \
&& echo 'SecAction "id:900000, phase:1, nolog, pass, t:none, setvar:tx.paranoia_level=2"' >> /usr/local/owasp-modsecurity-crs-3.2.0/crs-setup.conf \
&& chmod -R 777 /usr/local/owasp-modsecurity-crs-3.2.0
# Create combined config file
RUN touch /usr/local/modsec_includes.conf \
&& echo "include /ModSecurity/modsecurity.conf" >> /usr/local/modsec_includes.conf \
&& echo "include /usr/local/owasp-modsecurity-crs-3.2.0/crs-setup.conf" >> /usr/local/modsec_includes.conf \
&& echo "include /usr/local/owasp-modsecurity-crs-3.2.0/rules/*.conf" >> /usr/local/modsec_includes.conf \
&& chmod 777 /usr/local/modsec_includes.conf
# Make modifications to config
RUN sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /ModSecurity/modsecurity.conf \
&& sed -i "s/SecAuditLogType Serial/SecAuditLogType Concurrent/" /ModSecurity/modsecurity.conf \
&& sed -i "s|SecAuditLog /var/log/modsec_audit.log|SecAuditLog /usr/local/kong/logs/modsec_audit.log|" /ModSecurity/modsecurity.conf
######------ END OF ModSec NGINX WAF ------######
Then its worth noting, I am still using the kong openresty-build-tools deprecated lib for now, which allowed the adding of a 3rd party module with ease in its scripting, I am sure the newer repo offers that too . Note the
--add-module /ModSecurity-nginx
line, as my new additional arg.
RUN git clone https://github.com/kong/openresty-build-tools
RUN rm openresty-build-tools/kong-ngx-build
COPY kong-ngx-build openresty-build-tools/kong-ngx-build
RUN chmod -R 777 /openresty-build-tools
COPY patches/ngx/* /patches/
RUN cd openresty-build-tools \
&& mkdir work \
&& ./kong-ngx-build -p $KONG_PATH \
--openresty $RESTY_VERSION \
--openssl $RESTY_OPENSSL_VERSION \
--luarocks $RESTY_LUAROCKS_VERSION \
--add-module /ModSecurity-nginx \
#--pcre $PCRE_VERSION \
--force
Lastly in the nginx.conf produced by Kong you will want to ensure to include these within the server
or location
block of the conf so ModSec will run on your kong server inbound requests:
server {
server_name kong;
modsecurity on;
modsecurity_rules_file /usr/local/modsec_includes.conf;
Which enables ModSec and then a link to your file that contains rules/config references.
Then we thought up a number of threat vectors we wanted to validate security on. Some of the first that came to mind we check-listed against:
• Cross site scripting TESTED & VALIDATED IN P2 OWASP
• Jumbo Payload TESTED & VALIDATED IN P2 OWASP
• XML/JSON bomb (infinitely recursive data) TESTED & VALIDATED IN P2 OWASP
• Rate limiting (Kong does this)
• SQL Injection TESTED & VALIDATED IN P2 OWASP
So some examples of our tests to ensure ModSec was catching things was:
XML Bomb Payload:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
XSS
https://gateway.com/api/anonymous/user/test/v1?q=flowers+%3Cscript%3Eevil_script()%3C/script%3E
SQL INJECTION:
curl --request POST \
--url https://gateway.com/ \
--header 'content-type: application/x-www-form-urlencoded' \
--cookie dtCookie=36%24946B53A8A942C3A95C28C4CA0FD72AD2 \
--data 'item1=a'\'';DROP TABLE users; SELECT * FROM userinfo WHERE '\''t'\'' '
And well JUMBO payloads you get the point here, didn’t setup a remote XML doc that was massive though:
And a simple example of caught attack:
curl http://localhost:8000?exec=/bin/bash
And what shows up in your logging too:
FINAL THOUGHTS:
Final thoughts after this initial play around come to my next steps, which involve how to harden and minimize the rule-set for checks specific to the API Gateway space and relevant attack vectors, as well as productionalizing this WAF and minimizing the FP(false positives) associated with legitimate API transactions.
I began to ask a few q’s in Slack channels around modsec and owasp to gain more insight, these were what some folks had to say:
How to minimize rules quickly:
coderpatros 1 day ago
The rules have different tags.
So if you don’t use php you can SecRuleRemoveByTag “language-php” to remove a bunch of rules
you don’t need. Someone here might be able to link to a definitive list. But doing a find all
for “platform-” “language-” and “attack-” in the core rule set should bring them all back.
On the discussion of minimizing the rule-set for API Gateway use case:
dune73 10:25 AM (https://twitter.com/ChrFolini - Author of the #ModSecurity Handbook 2ed. OWASP @CoreRuleSet project co-lead and program chair @SwissCyberStorm.)
Jeremy, what you are probably looking for is a cut down version of rules that cause even less
FPs than PL1. We are thinking about such a thing, maybe developing it together with some CDNs
and internet hosters. It might be a rule exclusion package, or (new idea) a paranoia level 0.
For the time being, I would run PL1, don’t edit the rule set yourself, but disable the parts
of the ruleset you do not like / need with SecRuleRemoveById 9xxxxx-9yyyyy.FYI: I’m here at OWASP AppSecCali in Santa Monica. Yesterday I had a conversation with the new WAF teamlead from XYZ BIG CO and somebody from ABC BIG CO who works very closely with the WAF team. XYZ BIG CO runs now close to 100 Tbit/s over CRS. Not everything is blocking of course, and users need to pay to get access to the reports. But they run everything through CRS3. They are open to run experimental rules for us (to gauge the FP rate!) and they are also willing to share FPs with us. It sounds too good to be true. ABC BIG CO is more conservative, but they still use 10% of CRS3 on their traffic. Both companies agree that they combined control > 2/3 of the global internet traffic.
Cloudflare is just strong with the number of domains due to their free plan. But if this is about streaming the Olympics, it’s those guys. I’m a wee bit impressed.
My other thoughts would be how cool it would be someday to have OS Kong options to embed/enable the ModSec v3 with OWASP CRS3 or some trimmed down Kong approved rulset to run on Kong instances. This could all be done with Kong branded environment variables as is tradition and let Kong engineers do the heavy lifting with the build process in the background! Best OS API Gateway meets most adopted OS WAF+RuleSet in harmony ?
References:
https://coreruleset.org/faq/
https://owasp.slack.com/
Thanks for reading!