- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.7k
 
Description
Documentation on macro expansion says (https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#macro-expansion):  You can use macro expansion for operators that are "compiled" such @rx, etc. however you will have some impact in efficiency..
In V3, macro expansion in regexes is not performed and operator "@rx ^%{var}$" will match data against literal ^%{var}$.
The following code can be used for demonstration:
#include "modsecurity/modsecurity.h"
#include "modsecurity/rules.h"
static void logCb(void *data, const void *ruleMessagev) {
    std::cout << (char *) ruleMessagev << std::endl;
}
const char * req_uri = "/test?param=attack";
int main() {
    modsecurity::ModSecurity *modsec = new modsecurity::ModSecurity();
    modsecurity::Rules *rules = new modsecurity::Rules();
    modsecurity::Transaction * modsecTransaction;
    modsec->setServerLogCb(logCb, modsecurity::TextLogProperty);
    rules->loadFromUri("test.conf");
    modsecTransaction = new modsecurity::Transaction(modsec, rules, NULL);
    modsecTransaction->processURI(req_uri, "GET", "1.1");
    modsecTransaction->processRequestHeaders();
    modsecTransaction->processRequestBody();
    delete modsecTransaction;
    delete rules;
    delete modsec;
    return 0;
}With following test.conf:
SecAction "id:1, nolog, setvar:tx.bad_value=attack"
SecRule ARGS:param "@rx ^%{tx.bad_value}$" id:2
It won't produce expected alert because modsec will match param against literal ^%{tx.bad_value}$ instead of ^%attack$.
This breaks OWASP CRS rule 920420 which uses macro expansion of variable tx.allowed_request_content_type (this part of the rule will fire for any request because negated operator is used):
SecRule TX:0 "!^%{tx.allowed_request_content_type}$"