ModSecurity: Ignore Array ARGS - owasp

I want an exclusion rule for a request to be evaluated at runtime. The body of the request is an array. e.g
["somestring", "someRandomString",....]
This is the rule I have written:
SecRule REQUEST_URI "#beginsWith /my/url" \
              "phase:2,nolog,pass,id:10000,ctl:ruleRemoveTargetById=942100;ARGS"
However, the array ARGS are not excluded. I have not found anything about this in the online docs. Help would be appreciated.

Make sure this is defined before rule 942100.
ctl actions must be specified before the rules they alter, unlike SecRuleUpdateTargetById which must be specified after, confusingly enough.

Related

How to identify if there are any attachments in REQUEST_BODY for creating a ModSecurity exclusion rule

We are using ModSecurity CRS 3.0.2 and need to exclude rule 930110 which blocks requests if it contains patterns '../' and '..\'(Path Traversal Attack). If we attach a file while submitting the request, this pattern gets matched frequently and request is blocked which we want to avoid.
I was able to exclude the REQUEST_BODY using below:
SecRuleUpdateTargetById 930110 "!REQUEST_BODY"
Is there a way to exclude just the attachment and scan rest of the REQUEST_BODY?
If not, can we identify if REQUEST_BODY contains an attachment and exclude REQUEST_BODY only in this case. I tried string search as below but it doesn't work. 'filename' is a sample string in REQUEST_BODY I see whenever a file is attached.
SecRule REQUEST_BODY "#contains filename"
"id:1001,phase:1,pass,nolog,
ctl:ruleRemoveTargetById=930110;REQUEST_BODY"
REQUEST_URI filter works though
SecRule REQUEST_URI "#beginsWith /process"
"id:1001,phase:1,pass,nolog,
ctl:ruleRemoveTargetById=930110;REQUEST_BODY"

REST API - Handling an empty body in PATCH

I am currently contributing to a REST API written in Go and I was facing an existential question.
How are we supposed to handle an empty body in a PATCH? Knowing that a PATCH is used to update an existing data, are we supposed to return an error code (4XX) or an ok status (2XX)?
For example, if I have the following route: /user/:id
And a user has the following structure:
type User struct {
Name string
Email string
}
So if we PATCH a specific user, we will either have a body containing the name or the email.
What should we do if it is empty?
The RFC5789 was not a real help (2.2 for error handling)
https://datatracker.ietf.org/doc/rfc5789/?include_text=1
How are we supposed to handle an empty body in a PATCH?
That depends: what's wrong with an empty patch body?
If an empty patch body is an error, then your response should communicate the nature of the error to the client.
If the empty patch body is not an error, then apply the empty patch. That's probably a no-op, in which case, success! So you return a response that explains that applying empty patches is trivial, and here's where they can go to see the updated implementation. Alternatively, you can 204 as shown in the example. I don't see things explicitly spelled out, but I think you can draw upon the pattern described in RFC 7231 section 6.3.1.
Some examples that might help.
Suppose the client were using JSON Patch as the media type for the request. Now, a "JSON Patch document is a JSON [RFC4627] document that represents an array of objects". An empty request body is not a valid JSON document, and certainly isn't a valid array of objects, so that's a malformed patch document, and as described in section 2.2 you should be thinking about sending a 400 response.
Suppose the client were to send a json patch with an empty array of operations
[]
Semantically, that's a no-op -- except that a response indicating that the patch was successfully applied will invalidate cached values. So you could certainly report success (200) with not doing anything. You may be able to prevent the cached entries from being invalidated by returning an error (I think the Patch spec isn't quite describing the semantics correctly, but I don't see an errata filed).
A similar argument applies for application/merge-patch+json.
You may also want to consider the errata for RFC 5789
If a server receives a PATCH request with a media type whose specification does not define semantics specific to PATCH, the server SHOULD reject the request by returning the 415 Unsupported Media Type status code, unless a more specific error status code takes priority.
In particular, servers SHOULD NOT assume PATCH semantics for generic media types that don't define them, such as "application/xml" or "application/json".
The MDN used 204 No Content in an example here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH#response

allowing certain urls and deny the rest with robots.txt

I need to allow only some particular directories and deny the rest. It is my understanding that you should allow first then disallow the rest. Is this right what I have setup?
Allow: /word-lists/words-that-start-with/letter/z/
Allow: /word-lists/words-that-end-with/letter/z/
Disallow: /word-lists/words-that-start-with/letter/
Disallow: /word-lists/words-that-end-with/letter/
Your snippet looks OK, just don't forget to add a User-Agent at the top.
The order of the allow/disallow keywords doesn't matter currently, but it's up to the client to make the correct choice. See Order of precedence for group-member records section in our Robots.txt documentation.
[...] for allow and disallow directives, the most specific rule based on the length of the [path] entry will trump the less specific (shorter) rule.
The original RFC does state that clients should evaluate rules in the order they're found, however I don't recall any crawler that would actually do that, instead they're playing on the safe side and follow the most restrictive rule.
To evaluate if access to a URL is allowed, a robot must attempt to
match the paths in Allow and Disallow lines against the URL, in the
order they occur in the record. The first match found is used. If no
match is found, the default assumption is that the URL is allowed.

Mod security whitelist, multiple conditions

I've set up mod_security on my server with the Owasp predefined modsec rules.
However, I'm getting a lot of false positive so I've started to set up whitelist rules.
I have a false positive on this url:
http://example.com/fr/share/?u=http%3A%2F%2Fwww.example.com%2Fen%2Ffiles%2Fimgs%2F%3Fpage%3D100%2
with "Multiple URL Encoding Detected","OWASP_CRS/PROTOCOL_VIOLATION/EVASION"
due to the rule:
SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Multiple URL Encoding Detected',id:'1',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
So the main idea for me is to create a rule that still does the check except for the parameters "u" on url starting by /fr/share/?.
I have some hints with :
SecRule ARGS|!ARGS:u ... but how can I combine the mention where !REQUEST_URI equal to "/fr/share?.*"
So there are several options here.
You could rewrite the rule, and use chaining, to test for multiple conditions (note I've stripped off some of the rule actions for formatting reasons):
SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \
"phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8', \
t:none,block,msg:'Multiple URL Encoding Detected',id:'1',chain"
SecRule REQUEST_URI "!#beginsWith /fr/share/" "t:none"
The "chain" action means the rule on the next line must also pass before the actions are taken, so in this case it's checking the REQUEST_URI does not begin with /fr/share.
However this means you've got your own copy of this rule and makes upgrading to future versions of the Core Rule Set more difficult. It's much preferred to leave the original rule in place (which I've looked up and is actually rule id 950109 rather than rule id 1 that you've given so I presume that rule 1 is your copy).
So, to leave the original rule in place, but not have it false alerting you've a few options, detailed below in increasing complexity:
You could disable the whole rule:
SecRuleRemoveById 950109
This should be specified AFTER the rule is defined.
Obviously that's a bit extreme if it's only giving a false positive for one particular URL, parameter combination and means you lose the protection that rule is giving you for the any other url or parameter.
You could disable that rule for just that 'u' parameter:
SecRuleUpdateTargetById 950109 !ARGS:'u'
I think this can be specified before or after that rule is defined but not 100% sure on that.
But this will disable the for ALL 'u' parameters and you only want to disable it for this particular call, so slightly better but still not what you are looking for.
Therefore the best way is to use the ctl action, on a rule which matches the URL, to alter the original rule for that parameter:
SecRule REQUEST_URI "#beginsWith /fr/share/" \
"t:none,id:1,nolog,pass,ctl:ruleRemoveTargetById=950109;ARGS:u"
An almost identical request to what you are asking for, for rule 981260, is documented here:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#ctl

How to specify Header attributes in apiary documentation

Starting with Apiary, I'm currently specifying the APIs for our project.
I was able to define the definitions for the API and defining the parameters works great.
Now I would like to add also the values passed in the HTTP Headers into my documentation (like pagination, version number of the API,...)
When browsing through the documentation I found that headers could be adden within the payload block or the request block, but I want them to be displayed in the documentation.
Is this possible and what's the best way to achieve this?
You can now use the Headers section.
Parameters are actually not required to be present in the URL template.
Thus, what you can do is to just have
+ Parameters
+ id (required, number, `1`) ... Numeric `id` of the Note to perform action with. Has example value.
+ X-My-Header (required, number, `5469`) ... My header does something
and this is going to be rendered in the table you mentioned as well.
You are going to have a warning from the parser, but it should work as expected.