mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
perf. improvement/rx: Only compute dynamic regex in case of macro
On #1528 was added the support for macro expansion on @rx operator. The performance improvement suggested on the pull request was not thread safe, therefore removed. This patch adds a performance improvement on top of #1528. The benchmarks points to 10x faster results on OWASP CRS.
This commit is contained in:
parent
4a23891c85
commit
768a76a61e
@ -48,8 +48,20 @@ std::string MacroExpansion::expand(const std::string& input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MacroExpansion::containsMacro(std::string& input) {
|
||||||
|
size_t pos = input.find("%{");
|
||||||
|
size_t end = input.find("}");
|
||||||
|
|
||||||
|
if (pos == std::string::npos || end == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string MacroExpansion::expand(const std::string& input,
|
std::string MacroExpansion::expand(const std::string& input,
|
||||||
modsecurity::Rule *rule, Transaction *transaction) {
|
modsecurity::Rule *rule, Transaction *transaction) {
|
||||||
std::string res;
|
std::string res;
|
||||||
size_t pos = input.find("%{");
|
size_t pos = input.find("%{");
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ class MacroExpansion {
|
|||||||
return toupper(aa) == bb;
|
return toupper(aa) == bb;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool containsMacro(std::string& input);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,15 @@ namespace modsecurity {
|
|||||||
namespace operators {
|
namespace operators {
|
||||||
|
|
||||||
|
|
||||||
|
bool Rx::init(const std::string &arg, std::string *error) {
|
||||||
|
m_containsMacro = MacroExpansion::containsMacro(m_param);
|
||||||
|
if (m_containsMacro == false) {
|
||||||
|
m_re = new Regex(m_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rx::evaluate(Transaction *transaction, Rule *rule,
|
bool Rx::evaluate(Transaction *transaction, Rule *rule,
|
||||||
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
|
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
|
||||||
@ -39,8 +48,12 @@ bool Rx::evaluate(Transaction *transaction, Rule *rule,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string eparam = MacroExpansion::expand(m_param, transaction);
|
if (m_containsMacro) {
|
||||||
re = new Regex(eparam);
|
std::string eparam = MacroExpansion::expand(m_param, transaction);
|
||||||
|
re = new Regex(eparam);
|
||||||
|
} else {
|
||||||
|
re = m_re;
|
||||||
|
}
|
||||||
|
|
||||||
matches = re->searchAll(input);
|
matches = re->searchAll(input);
|
||||||
if (rule && rule->getActionsByName("capture").size() > 0 && transaction) {
|
if (rule && rule->getActionsByName("capture").size() > 0 && transaction) {
|
||||||
@ -62,7 +75,9 @@ bool Rx::evaluate(Transaction *transaction, Rule *rule,
|
|||||||
logOffset(ruleMessage, i.m_offset, i.m_length);
|
logOffset(ruleMessage, i.m_offset, i.m_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete re;
|
if (m_containsMacro) {
|
||||||
|
delete re;
|
||||||
|
}
|
||||||
|
|
||||||
if (matches.size() > 0) {
|
if (matches.size() > 0) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -36,17 +36,25 @@ class Rx : public Operator {
|
|||||||
public:
|
public:
|
||||||
/** @ingroup ModSecurity_Operator */
|
/** @ingroup ModSecurity_Operator */
|
||||||
Rx(std::string op, std::string param, bool negation)
|
Rx(std::string op, std::string param, bool negation)
|
||||||
: Operator(op, param, negation) {
|
: Operator(op, param, negation),
|
||||||
|
m_containsMacro(false) {
|
||||||
}
|
}
|
||||||
Rx(std::string name, std::string param)
|
Rx(std::string name, std::string param)
|
||||||
: Operator(name, param) {
|
: Operator(name, param),
|
||||||
|
m_containsMacro(false) {
|
||||||
}
|
}
|
||||||
explicit Rx(std::string param)
|
explicit Rx(std::string param)
|
||||||
: Operator("Rx", param) {
|
: Operator("Rx", param),
|
||||||
|
m_containsMacro(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~Rx() {
|
~Rx() {
|
||||||
|
if (m_containsMacro == false && m_re != NULL) {
|
||||||
|
delete m_re;
|
||||||
|
m_re = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool evaluate(Transaction *transaction, Rule *rule,
|
bool evaluate(Transaction *transaction, Rule *rule,
|
||||||
const std::string &input) override {
|
const std::string &input) override {
|
||||||
return evaluate(transaction, NULL, input, NULL);
|
return evaluate(transaction, NULL, input, NULL);
|
||||||
@ -58,6 +66,11 @@ class Rx : public Operator {
|
|||||||
bool evaluate(Transaction *transaction, Rule *rule,
|
bool evaluate(Transaction *transaction, Rule *rule,
|
||||||
const std::string& input,
|
const std::string& input,
|
||||||
std::shared_ptr<RuleMessage> ruleMessage) override;
|
std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||||
|
|
||||||
|
bool init(const std::string &arg, std::string *error);
|
||||||
|
private:
|
||||||
|
bool m_containsMacro;
|
||||||
|
Regex *m_re;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1027,6 +1027,11 @@ op_before_init:
|
|||||||
| OPERATOR_RX FREE_TEXT
|
| OPERATOR_RX FREE_TEXT
|
||||||
{
|
{
|
||||||
OPERATOR_CONTAINER($$, new operators::Rx($2));
|
OPERATOR_CONTAINER($$, new operators::Rx($2));
|
||||||
|
std::string error;
|
||||||
|
if ($$->init(driver.ref.back(), &error) == false) {
|
||||||
|
driver.error(@0, error);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| OPERATOR_STR_EQ FREE_TEXT
|
| OPERATOR_STR_EQ FREE_TEXT
|
||||||
{
|
{
|
||||||
|
@ -3,5 +3,3 @@ Include "../../modsecurity.conf-recommended"
|
|||||||
|
|
||||||
Include "owasp-v3/crs-setup.conf.example"
|
Include "owasp-v3/crs-setup.conf.example"
|
||||||
Include "owasp-v3/rules/*.conf"
|
Include "owasp-v3/rules/*.conf"
|
||||||
Include "owasp-v3/crs-setup.conf.example"
|
|
||||||
Include "owasp-v3/rules/*.conf"
|
|
||||||
|
@ -24,31 +24,8 @@
|
|||||||
|
|
||||||
using modsecurity::Transaction;
|
using modsecurity::Transaction;
|
||||||
|
|
||||||
char request_header[] = "" \
|
|
||||||
"GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\n\r" \
|
|
||||||
"Host: net.tutsplus.com\n\r" \
|
|
||||||
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5)" \
|
|
||||||
" Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\n\r" \
|
|
||||||
"Accept: text/html,application/xhtml+xml,application/xml; " \
|
|
||||||
"q=0.9,*/*;q=0.8\n\r" \
|
|
||||||
"Accept-Language: en-us,en;q=0.5\n\r" \
|
|
||||||
"Accept-Encoding: gzip,deflate\n\r" \
|
|
||||||
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n\r" \
|
|
||||||
"Keep-Alive: 300\n\r" \
|
|
||||||
"Connection: keep-alive\n\r" \
|
|
||||||
"Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\n\r" \
|
|
||||||
"Pragma: no-cache\n\r" \
|
|
||||||
"Cache-Control: no-cache\n\r";
|
|
||||||
|
|
||||||
char request_uri[] = "/test.pl?param1=test¶2=test2";
|
char request_uri[] = "/test.pl?param1=test¶2=test2";
|
||||||
|
|
||||||
char request_body[] = "";
|
|
||||||
|
|
||||||
char response_headers[] = "" \
|
|
||||||
"HTTP/1.1 200 OK\n\r" \
|
|
||||||
"Content-Type: text/xml; charset=utf-8\n\r" \
|
|
||||||
"Content-Length: length\n\r";
|
|
||||||
|
|
||||||
unsigned char response_body[] = "" \
|
unsigned char response_body[] = "" \
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\r" \
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\r" \
|
||||||
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
|
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
|
||||||
@ -69,7 +46,7 @@ const char* const help_message = "Usage: benchmark [num_iterations|-h|-?|--help]
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
unsigned long long NUM_REQUESTS(10000);
|
unsigned long long NUM_REQUESTS(1000000);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if (0 == strcmp(argv[1], "-h") ||
|
if (0 == strcmp(argv[1], "-h") ||
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v3
|
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git owasp-v3
|
||||||
cd owasp-v3
|
cd owasp-v3
|
||||||
git checkout v3.0.0 -b tag3.0.0
|
git checkout v3.0.2 -b tag3.0.2
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
echo 'Include "owasp-v3/crs-setup.conf.example"' >> basic_rules.conf
|
echo 'Include "owasp-v3/crs-setup.conf.example"' >> basic_rules.conf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user