mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Testing performance enhancements by enabling transformations cache
Also reduce the utilization of dynamic cast.
This commit is contained in:
parent
e641c3cc17
commit
2ee5d4ca8f
@ -36,6 +36,7 @@ class Action {
|
|||||||
: action_kind(2),
|
: action_kind(2),
|
||||||
action(_action),
|
action(_action),
|
||||||
name(_action),
|
name(_action),
|
||||||
|
m_isNone(false),
|
||||||
temporaryAction(false) {
|
temporaryAction(false) {
|
||||||
name.erase(0, 2);
|
name.erase(0, 2);
|
||||||
}
|
}
|
||||||
@ -43,6 +44,7 @@ class Action {
|
|||||||
: action_kind(kind),
|
: action_kind(kind),
|
||||||
action(_action),
|
action(_action),
|
||||||
name(_action),
|
name(_action),
|
||||||
|
m_isNone(false),
|
||||||
temporaryAction(false) {
|
temporaryAction(false) {
|
||||||
name.erase(0, 2);
|
name.erase(0, 2);
|
||||||
}
|
}
|
||||||
@ -94,6 +96,7 @@ class Action {
|
|||||||
|
|
||||||
virtual void fill_intervention(ModSecurityIntervention *intervention);
|
virtual void fill_intervention(ModSecurityIntervention *intervention);
|
||||||
bool temporaryAction;
|
bool temporaryAction;
|
||||||
|
bool m_isNone;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,12 +36,19 @@ namespace transformations {
|
|||||||
|
|
||||||
std::string HtmlEntityDecode::evaluate(std::string value,
|
std::string HtmlEntityDecode::evaluate(std::string value,
|
||||||
Assay *assay) {
|
Assay *assay) {
|
||||||
|
|
||||||
|
if (HtmlEntityDecodeInstantCache::getInstance().count(value) > 0) {
|
||||||
|
return HtmlEntityDecodeInstantCache::getInstance().at(value);
|
||||||
|
}
|
||||||
|
|
||||||
char *tmp = strdup(value.c_str());
|
char *tmp = strdup(value.c_str());
|
||||||
html_entities_decode_inplace((unsigned char *)tmp, value.size());
|
html_entities_decode_inplace((unsigned char *)tmp, value.size());
|
||||||
std::string ret("");
|
std::string ret("");
|
||||||
ret.assign(tmp);
|
ret.assign(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
|
HtmlEntityDecodeInstantCache::getInstance().emplace(value, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "actions/action.h"
|
#include "actions/action.h"
|
||||||
#include "actions/transformations/transformation.h"
|
#include "actions/transformations/transformation.h"
|
||||||
@ -29,6 +30,18 @@ namespace actions {
|
|||||||
namespace transformations {
|
namespace transformations {
|
||||||
|
|
||||||
|
|
||||||
|
class HtmlEntityDecodeInstantCache : public std::unordered_map<std::string, std::string> {
|
||||||
|
public:
|
||||||
|
static HtmlEntityDecodeInstantCache& getInstance() {
|
||||||
|
static HtmlEntityDecodeInstantCache instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HtmlEntityDecodeInstantCache() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class HtmlEntityDecode : public Transformation {
|
class HtmlEntityDecode : public Transformation {
|
||||||
public:
|
public:
|
||||||
explicit HtmlEntityDecode(std::string action)
|
explicit HtmlEntityDecode(std::string action)
|
||||||
|
@ -35,10 +35,18 @@ std::string LowerCase::evaluate(std::string value,
|
|||||||
Assay *assay) {
|
Assay *assay) {
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
|
|
||||||
|
if (LowerCaseInstantCache::getInstance().count(value) > 0) {
|
||||||
|
return LowerCaseInstantCache::getInstance().at(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string orig_value = value;
|
||||||
|
|
||||||
for (std::string::size_type i=0; i < value.length(); ++i) {
|
for (std::string::size_type i=0; i < value.length(); ++i) {
|
||||||
value[i] = std::tolower(value[i], loc);
|
value[i] = std::tolower(value[i], loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LowerCaseInstantCache::getInstance().emplace(orig_value, value);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "actions/action.h"
|
#include "actions/action.h"
|
||||||
#include "actions/transformations/transformation.h"
|
#include "actions/transformations/transformation.h"
|
||||||
@ -28,6 +29,17 @@ class Assay;
|
|||||||
namespace actions {
|
namespace actions {
|
||||||
namespace transformations {
|
namespace transformations {
|
||||||
|
|
||||||
|
class LowerCaseInstantCache : public std::unordered_map<std::string, std::string> {
|
||||||
|
public:
|
||||||
|
static LowerCaseInstantCache& getInstance() {
|
||||||
|
static LowerCaseInstantCache instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LowerCaseInstantCache() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class LowerCase : public Transformation {
|
class LowerCase : public Transformation {
|
||||||
public:
|
public:
|
||||||
|
@ -31,7 +31,8 @@ namespace transformations {
|
|||||||
class None : public Transformation {
|
class None : public Transformation {
|
||||||
public:
|
public:
|
||||||
explicit None(std::string action)
|
explicit None(std::string action)
|
||||||
: Transformation(action) { }
|
: Transformation(action)
|
||||||
|
{ m_isNone = true; }
|
||||||
|
|
||||||
std::string evaluate(std::string exp,
|
std::string evaluate(std::string exp,
|
||||||
Assay *assay) override;
|
Assay *assay) override;
|
||||||
|
@ -100,6 +100,10 @@ std::string UrlDecode::evaluate(std::string value,
|
|||||||
int invalid_count;
|
int invalid_count;
|
||||||
int changed;
|
int changed;
|
||||||
|
|
||||||
|
if (UrlDecodeInstantCache::getInstance().count(value) > 0) {
|
||||||
|
return UrlDecodeInstantCache::getInstance().at(value);
|
||||||
|
}
|
||||||
|
|
||||||
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
|
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
|
||||||
memcpy(val, value.c_str(), value.size() + 1);
|
memcpy(val, value.c_str(), value.size() + 1);
|
||||||
val[value.size()] = '\0';
|
val[value.size()] = '\0';
|
||||||
@ -112,6 +116,8 @@ std::string UrlDecode::evaluate(std::string value,
|
|||||||
|
|
||||||
free(val);
|
free(val);
|
||||||
|
|
||||||
|
UrlDecodeInstantCache::getInstance().emplace(value, out);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "actions/action.h"
|
#include "actions/action.h"
|
||||||
#include "actions/transformations/transformation.h"
|
#include "actions/transformations/transformation.h"
|
||||||
@ -28,6 +29,18 @@ class Assay;
|
|||||||
namespace actions {
|
namespace actions {
|
||||||
namespace transformations {
|
namespace transformations {
|
||||||
|
|
||||||
|
class UrlDecodeInstantCache : public std::unordered_map<std::string, std::string> {
|
||||||
|
public:
|
||||||
|
static UrlDecodeInstantCache& getInstance() {
|
||||||
|
static UrlDecodeInstantCache instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UrlDecodeInstantCache() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class UrlDecode : public Transformation {
|
class UrlDecode : public Transformation {
|
||||||
public:
|
public:
|
||||||
explicit UrlDecode(std::string action);
|
explicit UrlDecode(std::string action);
|
||||||
|
19
src/rule.cc
19
src/rule.cc
@ -140,8 +140,7 @@ bool Rule::evaluateActions(Assay *assay) {
|
|||||||
bool containsDisruptive = false;
|
bool containsDisruptive = false;
|
||||||
// int transformations = 0;
|
// int transformations = 0;
|
||||||
for (Action *a : this->actions_runtime_pre) {
|
for (Action *a : this->actions_runtime_pre) {
|
||||||
None *z = dynamic_cast<None *>(a);
|
if (a->m_isNone) {
|
||||||
if (z != NULL) {
|
|
||||||
none++;
|
none++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +164,6 @@ bool Rule::evaluateActions(Assay *assay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Action *a : this->actions_runtime_pre) {
|
for (Action *a : this->actions_runtime_pre) {
|
||||||
None *z = dynamic_cast<None *>(a);
|
|
||||||
/*
|
/*
|
||||||
if (none == 0) {
|
if (none == 0) {
|
||||||
value = a->evaluate(value, assay);
|
value = a->evaluate(value, assay);
|
||||||
@ -175,7 +173,7 @@ bool Rule::evaluateActions(Assay *assay) {
|
|||||||
transformations++;
|
transformations++;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (z != NULL) {
|
if (a->m_isNone) {
|
||||||
none--;
|
none--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,9 +279,7 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
std::list<std::string> exclusions;
|
std::list<std::string> exclusions;
|
||||||
for (int i = 0; i < variables->size(); i++) {
|
for (int i = 0; i < variables->size(); i++) {
|
||||||
Variable *variable = variables->at(i);
|
Variable *variable = variables->at(i);
|
||||||
Exclusion *exl = dynamic_cast<Exclusion *>(variable);
|
if (variable->m_isExclusion) {
|
||||||
|
|
||||||
if (exl != NULL) {
|
|
||||||
std::list<transaction::Variable *> *z =
|
std::list<transaction::Variable *> *z =
|
||||||
variable->evaluate(assay);
|
variable->evaluate(assay);
|
||||||
for (auto &y : *z) {
|
for (auto &y : *z) {
|
||||||
@ -297,8 +293,7 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
for (int i = 0; i < variables->size(); i++) {
|
for (int i = 0; i < variables->size(); i++) {
|
||||||
int transformations = 0;
|
int transformations = 0;
|
||||||
Variable *variable = variables->at(i);
|
Variable *variable = variables->at(i);
|
||||||
Exclusion *exl = dynamic_cast<Exclusion *>(variable);
|
if (variable->m_isExclusion) {
|
||||||
if (exl != NULL) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,8 +312,7 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
std::string value = v->m_value;
|
std::string value = v->m_value;
|
||||||
int none = 0;
|
int none = 0;
|
||||||
for (Action *a : this->actions_runtime_pre) {
|
for (Action *a : this->actions_runtime_pre) {
|
||||||
None *z = dynamic_cast<None *>(a);
|
if (a->m_isNone != NULL) {
|
||||||
if (z != NULL) {
|
|
||||||
none++;
|
none++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +336,6 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Action *a : this->actions_runtime_pre) {
|
for (Action *a : this->actions_runtime_pre) {
|
||||||
None *z = dynamic_cast<None *>(a);
|
|
||||||
if (none == 0) {
|
if (none == 0) {
|
||||||
value = a->evaluate(value, assay);
|
value = a->evaluate(value, assay);
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
@ -352,7 +345,7 @@ bool Rule::evaluate(Assay *assay) {
|
|||||||
#endif
|
#endif
|
||||||
transformations++;
|
transformations++;
|
||||||
}
|
}
|
||||||
if (z != NULL) {
|
if (a->m_isNone != NULL) {
|
||||||
none--;
|
none--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,9 @@ namespace Variables {
|
|||||||
|
|
||||||
Variable::Variable(std::string name)
|
Variable::Variable(std::string name)
|
||||||
: m_name(name),
|
: m_name(name),
|
||||||
m_collectionName("") {
|
m_collectionName(""),
|
||||||
|
m_isExclusion(false),
|
||||||
|
m_isCount(false) {
|
||||||
|
|
||||||
if (m_name.at(0) == '\\') {
|
if (m_name.at(0) == '\\') {
|
||||||
m_type = RegularExpression;
|
m_type = RegularExpression;
|
||||||
@ -53,7 +55,9 @@ Variable::Variable(std::string name)
|
|||||||
Variable::Variable(std::string name, VariableKind kind)
|
Variable::Variable(std::string name, VariableKind kind)
|
||||||
: m_name(name),
|
: m_name(name),
|
||||||
m_collectionName(""),
|
m_collectionName(""),
|
||||||
m_kind(kind) {
|
m_kind(kind),
|
||||||
|
m_isExclusion(false),
|
||||||
|
m_isCount(false) {
|
||||||
|
|
||||||
if (m_name.at(0) == '\\') {
|
if (m_name.at(0) == '\\') {
|
||||||
m_type = RegularExpression;
|
m_type = RegularExpression;
|
||||||
|
@ -74,6 +74,8 @@ class Variable {
|
|||||||
|
|
||||||
VariableType m_type;
|
VariableType m_type;
|
||||||
VariableKind m_kind;
|
VariableKind m_kind;
|
||||||
|
bool m_isExclusion;
|
||||||
|
bool m_isCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,8 @@ class Exclusion : public Variable {
|
|||||||
public:
|
public:
|
||||||
explicit Exclusion(Variable *v)
|
explicit Exclusion(Variable *v)
|
||||||
: Variable(v->m_name),
|
: Variable(v->m_name),
|
||||||
var(v) { }
|
var(v)
|
||||||
|
{ m_isExclusion = true; }
|
||||||
|
|
||||||
std::list<transaction::Variable *> *
|
std::list<transaction::Variable *> *
|
||||||
evaluate(Assay *assay) override;
|
evaluate(Assay *assay) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user