0

I was hoping to see if there was an easier, better, more efficient way of doing this. We get legit traffic that has 'xhtml' in the body of the request. the owasp 941130 regex matches xhtml and blocks it.

Relevant part of rule:

SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\S](?:!ENTITY\s+(?:\S+|%\s+\S+)\s+(?:PUBLIC|SYSTEM)|x(?:link:href|html|mlns)|data:text\/html|pattern\b.*?=|formaction|\@import|;base64)\b" \
"id:941130,\

The test I'm sending (watered down):

`curl -v 'http://localhost/s/blob-storage/api/v1/blobs/ABCDEF?action=download&&&response_content_type=application%2Fxhtml%2Bxml`'

Relevent info from modsecurity audit log:

ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?i)[\s\S](?:!ENTITY\s+(?:\S+|%\s+\S+)\s+(?:PUBLIC|SYSTEM)|x(?:link:href|html|mlns)|data:text\/html|pattern\b.*?=|formaction|\@import|;base64)\b' against variable `ARGS:response_content_type' (Value: `application/xhtml+xml' )

I've tried a few things; I can simply disable the rule and do a complete rewrite in crs-after, not bad for one rule but I'm going to have a lot to go through. The following two work BUT I'm not sure how I feel with shutting off the rule based on a URI match, that means its not looking for xlink, xhref, xmlns. These both work:

SecRule REQUEST_URI "@rx /s/blob-storage/api/v1" "id:9500001, phase:1, t:none, pass, nolog, ctl:ruleRemoveById=941130"
SecRule REQUEST_URI "@beginsWith /s/blob-storage/api/" "id:9500001, phase:1, t:none, pass, nolog, ctl:ruleRemoveById=941130"

I have seen similar posts talking about using SecRuleUpdateTargetById but I haven't had any luck, examples:

SecRuleUpdateTargetById 941130 "!ARGS:response_content_type:/^application/xhtml*/"
SecRuleUpdateTargetById 941130 "!ARGS_NAMES:*application/xhtml*"

Basically I just want to stop it from matching XHTML. Any better ways?

jmallett
  • 1
  • 1

1 Answers1

3

I'm not sure there isn't any easier, better, more efficient way to avoid this FP than you create an exclusion - as you mentioned and solved.

Using the proposed solution is fine, if that works that's enough for you. Just one thing: you should exclude only the affected argument, not the whole rule, like this:

SecRule REQUEST_URI "@beginsWith /s/blob-storage/api/" \
    "id:9900001,\
    phase:1,\
    t:none,\
    pass,\
    nolog,\
    ctl:ruleRemoveTargetById=941130;ARGS:response_content_type"

Basically I just want to stop it from matching XHTML. Any better ways?

To do this, you have to rewrite the complete rule.

airween
  • 6,203
  • 1
  • 14
  • 20
  • Thank you, that may be the best route. I just started playing around and found I could do: `SecRuleUpdateTargetById 941130 "!ARGS:response_content_type"` When I tried to add on the application/xhtml I couldn't get it to work. I guess none of the Value is parsed. I think you're way will be the best. Thanks again! the other thought i had was if I'm going to write a secrule I could just disable 941130 and write the full rule the way i need it (minus the xhtml) in crs-after. – jmallett Feb 24 '22 at 07:38
  • 2
    "I guess none of the Value is parsed" - well, perhaps the problem is that the engine must to know the value to ignore it :). You can change/replace the rule, but don't forget to update it when you upgrade the CRS version. Note, that this answer has created CRS's Dev-on-duty program. – airween Feb 24 '22 at 08:16