Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Documentation for the Vertical Bar and the Semicolon #3331

Open
thekief opened this issue Jan 20, 2025 · 8 comments
Open

Add Documentation for the Vertical Bar and the Semicolon #3331

thekief opened this issue Jan 20, 2025 · 8 comments

Comments

@thekief
Copy link

thekief commented Jan 20, 2025

I recently re-read the documentation and noticed that the vertical bar and the semicolon are used in a lot of examples without properly explaining their usage.

Please correct me, if I'm wrong but there seems no explicit documentation for these symbols in the wiki. In general it's really hard to find information, as most blogs just reference the official wiki. Especially for beginners it would be helpful to have an overview, what, e.g. SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* ... does and why it is useful.

@thekief
Copy link
Author

thekief commented Jan 20, 2025

Sorry to hijack this issue for another documentation issue, but I also noticed that for example ARGS:json also requires quite a lot of implicit knowledge.

@airween
Copy link
Member

airween commented Jan 20, 2025

Hi @thekief,

thanks for reporting this, and I have to tell you I see your pain. Years ago when I started to explore ModSecurity, I was in same situation.

Short: pipes (|) are used to make an "OR" connection, so after the keyword you can list all targets what you want to inspect. In your example, you can consider REQUEST_FILENAME OR ARGS_NAMES OR ARGS and so on. The "OR" relationship here is a permissive.

The double colon is used to refer the key of a collection. For eg. ARGS is a collection, because it stores all arguments (both GET and POST). You can access the specified key with help of :. In your example, if you want to inspect only the json key in request arguments, you can use ARGS:json. Or if you want to make an exclusion, you can also use this syntax.

If you have any idea how can we extend the documentation, please let us know. Or feel free to make a patch (you can clone the wiki from GH).

@thekief
Copy link
Author

thekief commented Jan 20, 2025

Thank you for your fast answer,I really appreciate it.

Like probably most people, I'm working off the OWASP CRS and sometimes I have to disable things. My biggest concern is that I accidentally do something that has some unintended side-effect or might miss maybe a really cool feature that cuts down my rule by half.

To sum the answer so far:

  • | is an "or"
  • ; is an "and"

And a few extra questions:

  • ARGS, ARGS_GET, ARGS_POST allow to access JSON using ARGS:json. Are there further version for, e.g. YAML, XML?
  • regarding the ARGS extensions:
    • PUT commonly has a body, DELETE sometimes too. Can it be accessed using ARGS_POST?
    • strictly speaking GET allows a body, but the documentation only allows to get the parameters. Does that hold up, if this edge case arises?
  • are there other "boolean" operations besides the "and" and "or"?

p.s. I will collect some feedback from colleagues and look into opening into a PR
p.p.s. Is there by chance a really cool feature that's not explicitly documented but you would to shed light at? 😄

@airween
Copy link
Member

airween commented Jan 20, 2025

Like probably most people, I'm working off the OWASP CRS and sometimes I have to disable things. My biggest concern is that I accidentally do something that has some unintended side-effect or might miss maybe a really cool feature that cuts down my rule by half.

You're completely right. You (and anyone else) must be sure to avoid any unwanted side effect.

To sum the answer so far:

* `|` is an "or"

yes,

* `;` is an "and"

no, there is no such meaning. I mentioned :, but the meaning is not "and".

And a few extra questions:

* `ARGS, ARGS_GET, ARGS_POST`  allow to access JSON using `ARGS:json`. Are there further version for, e.g. YAML, XML?

no, this is a wrong interpretation.

ARGS, ARGS_GET, ARGS_POST and many other targets are collections. This means the target holds key:value pairs.

Consider a GET request:

...?a1=foo&a2=bar&json=false

In this case, the ARGS and ARGS_GET collections will look like:
a1: foo
a2:bar
json:false

Please note that the json here is "just" a key, there is no any connection to JSON content.

* regarding the `ARGS` extensions:
  * `PUT` commonly has a body, `DELETE` sometimes too. Can it be accessed using `ARGS_POST`?

No. ARGS_GET and ARGS_POST will contain request variables if the method is GET or POST, see documentation: 1, 2.

ARGS can hold the processed body, but it depends what's the content type. If the Content-Type is x-www-form-urlencoded, then the engine tries to unpack it into ARGS. If the header is application/json then ARGS will hold the concatenated JSON keys as key and the values as value.

  * strictly speaking `GET` allows a body, but the documentation only allows to get the parameters. Does that hold up, if this edge case arises?

Speaking of CRS, (if I'm not wrong) it handles this. ARGS_GET will filled from the query string, see mentioned documentation above. Regarding to your question: yes, theoretically it is possible to send a GET request with a payload, but as the RFC says: "A payload within a GET request message has no defined semantics;". I've never seen this before, and this is more an HTTP server question than the WAF module.

* are there other "boolean" operations besides the "and" and "or"?

Just clarify: there is no "and" operation. So, there is no explicit "and" operation. You can make an "and" relation with chain action. This means you can write two or more SecRule, and if the N-th rule returns true then the next one will be evaluated, otherwise not.

p.s. I will collect some feedback from colleagues and look into opening into a PR p.p.s. Is there by chance a really cool feature that's not explicitly documented but you would to shed light at? 😄

Uh, that's a good question. The problem is that there are two documentations, one for mod_security2 and another one for libmodsecurity3. Libmodsecurity3 based on mod_security2's, which is (probably) not up to date, therefore - I have a feeling - libmodsecurity3 documentation also has some leaks. But - unfortunately - we don't have enough capacity to maintain them.

@thekief
Copy link
Author

thekief commented Jan 20, 2025

Thank you for the thorough answer. Two questions arose from your answer:

no, there is no such meaning. I mentioned :, but the meaning is not "and".

Sorry, that was some terrible phrasing from my side. Let's consider this example from the wiki:

# white-list the user parameter for rule #981260 when the REQUEST_URI is /index.php
SecRule REQUEST_URI "@beginsWith /index.php" "phase:1,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById=981260;ARGS:user

The ; denotes more of an for right to my understanding:

if this path matches, remove the rule for the argument user

Is that a correct interpretation?

ARGS, ARGS_GET, ARGS_POST and many other targets are collections. This means the target holds key:value pairs.

I am a bit confused of this answer in the, e.g. the context of #2942. To my understanding when processing a body, ARGS:json allows to access the body.

@airween
Copy link
Member

airween commented Jan 21, 2025

Sorry, that was some terrible phrasing from my side. Let's consider this example from the wiki:

# white-list the user parameter for rule #981260 when the REQUEST_URI is /index.php
SecRule REQUEST_URI "@beginsWith /index.php" "phase:1,t:none,pass, \
  nolog,ctl:ruleRemoveTargetById=981260;ARGS:user

The ; denotes more of an for right to my understanding:

if this path matches, remove the rule for the argument user

Is that a correct interpretation?

yes. ; is an item of the SecLang.

Even more clearly: consider the mentioned exclusion without part ;ARGS:user

ctl:ruleRemoveTargetById=981260

In this case you completely remove the whole rule if the URI is /index.php. If you don't want to remove the rule completely, but you don't want to make it any intervention if the argument name is user, then you can use this syntax.

ARGS, ARGS_GET, ARGS_POST and many other targets are collections. This means the target holds key:value pairs.

I am a bit confused of this answer in the, e.g. the context of #2942. To my understanding when processing a body, ARGS:json allows to access the body.

Ah, sorry - yes, you're right (but it wasn't visible in the context above). And now I can see this is a bit confusing.

So, yes, if the content type is JSON, and the engine parses it as JSON, then the variables will be storing in ARGS, and all key starts with json. Example:

{"root": {"level1": {"level2": {"a":1,"b":"foo"}}}}

then the parser will fill the ARGS like this: root.level1.level2.a:1, root.level1.level2.a:foo.

But if the request is an x-www-form-urlencoded, and one of the argument name is json, then that will be accessible also with ARGS:json.

Hope this helps.

@thekief
Copy link
Author

thekief commented Jan 21, 2025

So, yes, if the content type is JSON, and the engine parses it as JSON, then the variables will be storing in ARGS, and all key starts with json. Example:

To go back to my previous question in this regard:

Is there some special handling for further data types, such as XML?

@airween
Copy link
Member

airween commented Feb 12, 2025

@thekief sorry for the late answer.

Is there some special handling for further data types, such as XML?

I don't think so XML is a special target - or could you help me to clarify what do you mean "special handling"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants