corazawaf / coraza

OWASP Coraza WAF is a golang modsecurity compatible web application firewall library
https://www.coraza.io
Apache License 2.0
2.15k stars 211 forks source link

SecRuleUpdateTargetByTag in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS doesn't seem to work (Caddy) #1018

Closed ErazerBrecht closed 5 months ago

ErazerBrecht commented 6 months ago

Description

I'm currently in the works of converting a Modsecurity (on Apache) instance to Coraza (on Caddy). Everything went rather smooth. But I'm stuck on converting an exclusion I have in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.

I have added this line: SecRuleUpdateTargetByTag "attack-xss" "!ARGS:search"

This should stop preventing Coraza from triggering on XSS payloads in a queryparam called 'search'.

Steps to reproduce

Here is my code: https://github.com/ErazerBrecht/coraza-poc

It's a rather plain Caddy webserver using the official Coraza Caddy module It contains a docker container you could easily run

docker build . -t coraza-poc:0.0.1 docker run -p 7543:80 coraza-poc:0.0.1

Expected result

200 OK when going to http://localhost:7543/?search=javascript\x3Ajavascript:alert(1)

Actual result

403 FORBIDDEN

Logs:

{
   "level":"error",
   "ts":1710602290.747456,
   "logger":"http.handlers.waf",
   "msg":"[client \"172.17.0.1\"] Coraza: Access denied (phase 2). NoScript XSS InjectionChecker: Attribute Injection [file \"@owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf\"] [line \"4749\"] [id \"941170\"] [rev \"\"] [msg \"NoScript XSS InjectionChecker: Attribute Injection\"] [data \"Matched Data: javascript:javascript:alert( found within ARGS:search: javascript:javascript:alert(1)\"] [severity \"critical\"] [ver \"OWASP_CRS/4.0.0-rc1\"] [maturity \"0\"] [accuracy \"0\"] [tag \"application-multi\"] [tag \"language-multi\"] [tag \"platform-multi\"] [tag \"attack-xss\"] [tag \"paranoia-level/1\"] [tag \"OWASP_CRS\"] [tag \"capec/1000/152/242\"] [hostname \"\"] [uri \"/?search=javascript\\\\x3Ajavascript:alert(1)\"] [unique_id \"xmBdzcGCZYzARcdx\"]\n"
}
{
   "level":"error",
   "ts":1710602290.747562,
   "logger":"http.handlers.waf",
   "msg":"[client \"172.17.0.1\"] Coraza: Access denied (phase 2). IE XSS Filters - Attack Detected [file \"@owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf\"] [line \"4825\"] [id \"941210\"] [rev \"\"] [msg \"IE XSS Filters - Attack Detected\"] [data \"Matched Data: javascript:j found within ARGS:search: javascript:javascript:alert(1)\"] [severity \"critical\"] [ver \"OWASP_CRS/4.0.0-rc1\"] [maturity \"0\"] [accuracy \"0\"] [tag \"application-multi\"] [tag \"language-multi\"] [tag \"platform-multi\"] [tag \"attack-xss\"] [tag \"paranoia-level/1\"] [tag \"OWASP_CRS\"] [tag \"capec/1000/152/242\"] [hostname \"\"] [uri \"/?search=javascript\\\\x3Ajavascript:alert(1)\"] [unique_id \"xmBdzcGCZYzARcdx\"]\n"
}
{
   "level":"error",
   "ts":1710602290.7476447,
   "logger":"http.handlers.waf",
   "msg":"[client \"172.17.0.1\"] Coraza: Access denied (phase 2). Javascript method detected [file \"@owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf\"] [line \"5091\"] [id \"941390\"] [rev \"\"] [msg \"Javascript method detected\"] [data \"Matched Data: alert( found within ARGS:search: javascript:javascript:alert(1)\"] [severity \"critical\"] [ver \"OWASP_CRS/4.0.0-rc1\"] [maturity \"0\"] [accuracy \"0\"] [tag \"application-multi\"] [tag \"language-multi\"] [tag \"attack-xss\"] [tag \"paranoia-level/1\"] [tag \"OWASP_CRS\"] [tag \"capec/1000/152/242\"] [hostname \"\"] [uri \"/?search=javascript\\\\x3Ajavascript:alert(1)\"] [unique_id \"xmBdzcGCZYzARcdx\"]\n"
}
{
   "level":"error",
   "ts":1710602290.7481065,
   "logger":"http.handlers.waf",
   "msg":"[client \"172.17.0.1\"] Coraza: Access denied (phase 2). Inbound Anomaly Score Exceeded (Total Score: 15) [file \"@owasp_crs/REQUEST-949-BLOCKING-EVALUATION.conf\"] [line \"7037\"] [id \"949110\"] [rev \"\"] [msg \"Inbound Anomaly Score Exceeded (Total Score: 15)\"] [data \"\"] [severity \"emergency\"] [ver \"OWASP_CRS/4.0.0-rc1\"] [maturity \"0\"] [accuracy \"0\"] [tag \"anomaly-evaluation\"] [hostname \"\"] [uri \"/?search=javascript\\\\x3Ajavascript:alert(1)\"] [unique_id \"xmBdzcGCZYzARcdx\"]\n"
}
ErazerBrecht commented 6 months ago

Smaller reproduction This loads a minimal set of rules but still has the same problem

{
    order coraza_waf first
}

:80 {
 coraza_waf {
  load_owasp_crs
  directives `
   Include /opt/coraza/config/coraza.conf
   Include /opt/coraza/config/crs-setup.conf
   Include @owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf
   Include @owasp_crs/REQUEST-949-BLOCKING-EVALUATION.conf
   Include /opt/coraza/config/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
  `
 }
}
M4tteoP commented 6 months ago

Hi @ErazerBrecht, thanks for the report and the examples. SecRuleUpdateTargetByTag is currently not supported, but the implementation should be quite straightforward and definitely needed. I'm planning to open a PR this week, hopefully even tomorrow.

M4tteoP commented 6 months ago

I opened https://github.com/corazawaf/coraza/pull/1020 which should address the implementation of SecRuleUpdateTargetByTag.

If you wish to early test it, you can point to this coraza-caddy branch: https://github.com/corazawaf/coraza-caddy/tree/updatetargetbytag, which already brings in my PR just for testing purposes. You should be able to build it with xcaddy build --with github.com/corazawaf/coraza-caddy/v2@b75ce169b56b5d65eb30f22d0fea4a1aee4252e6.

I did a quick test as the following:

:8080 {
  coraza_waf {
    load_owasp_crs
    directives `
    Include @coraza.conf-recommended
    Include @crs-setup.conf.example
    SecRuleEngine On
    Include @owasp_crs/REQUEST-901-INITIALIZATION.conf
    Include @owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf
    Include @owasp_crs/REQUEST-949-BLOCKING-EVALUATION.conf
    SecRuleUpdateTargetByTag attack-xss "!ARGS:search"
    `
  }
  reverse_proxy {$HTTPBIN_HOST:localhost}:8081
}
▶ curl -I localhost:8080/
HTTP/1.1 200 OK

▶ curl -I 'localhost:8080/?search=javascript\x3Ajavascript:alert(1)'
HTTP/1.1 200 OK

▶ curl -I 'localhost:8080/?search2=javascript\x3Ajavascript:alert(1)'
HTTP/1.1 403 Forbidden

Any feedback is appreciated!

ErazerBrecht commented 6 months ago

@M4tteoP I'll make sure to check this out today! Already many thanks for your fast response and fix 🚀

ErazerBrecht commented 6 months ago

@M4tteoP Works like a charm Thank you for your very fast fix! Greatly appreciated!

Enjoy the rest of the week! (You already made mine) Sincerely, Brecht