Add an Option to Skip Body Inspections ( Closes #343 )#356
Conversation
|
Hi @thekief, thanks for this PR, I think this is quite useful.
If I suggest suggest a method:
For the response body skip:
You can add cross checking too (eg. the first mentioned rule above executes in |
|
Sorry for getting back so late. I created configurations, but as I'm terrible with nginx tests using Perl, may I just send you the configurations? 😅 |
|
The abbreviation for |
|
|
@HanadaLee thank you for looking over the changes. I use |
|
@thekief could you rebase your PR? Then we can find some solution for testing. |
5b6773f to
be595e7
Compare
|
Done. I also had to add another commit to address the number of directives mentioned in the readme. |
34d6b15 to
1d4d37a
Compare
|
|
I found several blocking issues in the current implementation. In particular, the request-side directive currently disables much more than request-body inspection, and the new configuration fields do not inherit correctly.
In ngx_http_modsecurity_access_handler(), the new check returns before the ModSecurity context and transaction are created: This does not only skip request-body buffering. It also skips: connection processing; Because no context is created, the response filters and log handler subsequently treat ModSecurity as disabled for the entire request. This contradicts the intended behavior described in issue #343, which is to skip body inspection while preserving the other ModSecurity checks. The skip check should be moved after the transaction, URI, and request headers have been processed. It should only bypass ngx_http_read_client_request_body() and the body-appending logic. The intended phase 2 behavior should also be defined explicitly. It may still be necessary to call: without appending body data, so that phase 2 rules that do not depend on request-body variables can still run.
The fields are allocated through ngx_pcalloc(), so they initially have the value 0. They are not initialized to NGX_CONF_UNSET, and they are not handled in ngx_http_modsecurity_merge_conf(). As a result, a configuration such as: server { } does not enable the option inside /upload, because the child location has its own zero-initialized value. Please initialize both fields in ngx_http_modsecurity_create_conf(): and merge them in ngx_http_modsecurity_merge_conf(): Without this, the documented http and server contexts do not work as expected.
The PR changes: to: The custom ngx_http_modsecurity_get_module_ctx() helper is important because it restores the transaction context from the request-pool cleanup handlers when the module context has been cleared, for example after an internal redirect. Using ngx_http_get_module_ctx() directly can therefore cause response-body inspection to be silently skipped after an internal redirect. This is a regression even when both new directives are disabled. The original helper should continue to be used.
The response header filter unconditionally sets: The new skip_resp_body_filter check only happens later in the body filter. Therefore, Nginx is still told that the response body must be kept in memory even when response-body inspection is disabled. To achieve the intended resource-saving behavior, the configuration should also be checked in the header filter: Response-header processing should still continue normally. The phase 4 behavior should also be clarified. Completely skipping msc_process_response_body() skips all phase 4 rules, including rules that may not depend on RESPONSE_BODY.
There are also several documentation issues: The README says the connector adds seven directives, but there are six existing directives plus two new ones, so the total should be eight. Tests should cover at least: phase 1 rules still running when request-body inspection is skipped; |
|
Hey @HanadaLee , Regarding the documentation and the number of directives: tbh, I'm not involded with any If you want, I can check if I can find the intial patch and maybe you can get it merged. Otherwise, I'd close it as I don't want to keep it open without any progress. |
Alright, if you don't mind, I'll probably submit a new PR based on your work, since I really need this feature. |
|
@HanadaLee: first of all, thank you for your participation. @thekief and @HanadaLee: I would like to let you know guys that I've been working on v4, where there will be some new features in API, eg. the application can ask the engine does it need to send the request body for the check (based on Also please note, that there is a known wrong behavior, described in ModSecurity/#2465, which needs to be fixed before we touch this part of API. I plan to fix it in v4 too. |
I am excited to see a brand-new version of ModSecurity on the horizon. I am currently planning to add support for the following features and hope they can be considered during development:
|
|
@airween is this PR something you'd see as something that directly relates to/affects owasp-modsecurity/ModSecurity#2465 ? |
Just for the record: it's not a brand new 😃. But we definitely need to extend the API, therefore we need to increase the version.
No, that's different. We should solve that inside of the library. I'll reply your listed items later. |



As dicussed in the issue, I would like to add 2 new directives that allow to skip the body inspection. There are a few usecases, where, e.g. encrypted data is set, and no useful inspection can be made.
While denying the body access may skip the inspection, it still results in the caching of data. Subsequently, there is an unneeded amount of resource consumption, memory, as well as time, involved.
While it would be cleaner to expose an API that allows users of
libmodsecurityto check, if a path, e.g. has a reqeust body check, this involves a lot more work. The approach taken in this PR, shifts the functionality to that is only necessitates changes in thenginxmodule.Regarding Tests: As for tests, I'm a bit unsure what the best way would be to test it. One way would be to try to upload a file, e.g. 100MB, to a location and check when the first data reaches it. If the body inspection is disabled, the first bytes will arrive much sooner, as the
nginxmodule caches the body until it's fully received otherwise and only then forwards the data.