Makes operator to use string_view

This commit is contained in:
Felipe Zimmerle 2019-03-05 12:26:44 -03:00
parent 1e9c54860b
commit 8e3e9b8be7
85 changed files with 1954 additions and 298 deletions

View File

@ -27,10 +27,13 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#include "modsecurity/string_view.hpp"
#endif #endif
#include "modsecurity/variable_value.h" #include "modsecurity/variable_value.h"
#ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_ #ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_ #define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_
@ -79,6 +82,12 @@ class AnchoredSetVariable : public std::unordered_multimap<std::string,
void set(const std::string &key, const std::string &value, void set(const std::string &key, const std::string &value,
size_t offset); size_t offset);
void set(const std::string &key, const bpstd::string_view &value,
size_t offset);
void set(const std::string &key, const char *value,
size_t offset);
void set(const std::string &key, const std::string &value, void set(const std::string &key, const std::string &value,
size_t offset, size_t len); size_t offset, size_t len);

View File

@ -26,10 +26,14 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <cstring>
#include "modsecurity/string_view.hpp"
#endif #endif
#include "modsecurity/variable_value.h" #include "modsecurity/variable_value.h"
#ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_ #ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_ #define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_
@ -59,6 +63,8 @@ class AnchoredVariable {
void unset(); void unset();
void set(const std::string &a, size_t offset); void set(const std::string &a, size_t offset);
void set(const bpstd::string_view &a, size_t offset);
void set(const char *a, size_t offset);
void set(const std::string &a, size_t offset, size_t offsetLen); void set(const std::string &a, size_t offset, size_t offsetLen);
void append(const std::string &a, size_t offset, void append(const std::string &a, size_t offset,
bool spaceSeparator = false); bool spaceSeparator = false);

File diff suppressed because it is too large Load Diff

View File

@ -49,11 +49,13 @@ pkginclude_HEADERS = \
../headers/modsecurity/rules_set_phases.h \ ../headers/modsecurity/rules_set_phases.h \
../headers/modsecurity/rules_set_properties.h \ ../headers/modsecurity/rules_set_properties.h \
../headers/modsecurity/rules_exceptions.h \ ../headers/modsecurity/rules_exceptions.h \
../headers/modsecurity/string_view.hpp \
../headers/modsecurity/transaction.h \ ../headers/modsecurity/transaction.h \
../headers/modsecurity/variable_origin.h \ ../headers/modsecurity/variable_origin.h \
../headers/modsecurity/variable_value.h ../headers/modsecurity/variable_value.h
libmodsecurity_includesub_collection_HEADERS = \ libmodsecurity_includesub_collection_HEADERS = \
../headers/modsecurity/collection/collection.h \ ../headers/modsecurity/collection/collection.h \
../headers/modsecurity/collection/collections.h ../headers/modsecurity/collection/collections.h

View File

@ -80,6 +80,36 @@ void AnchoredSetVariable::set(const std::string &key,
} }
void AnchoredSetVariable::set(const std::string &key,
const bpstd::string_view &value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *v = new std::string(value.c_str());
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset;
origin->m_length = value.size();
var->addOrigin(std::move(origin));
emplace(key, var);
}
void AnchoredSetVariable::set(const std::string &key,
const char *value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *v = new std::string(value);
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset;
origin->m_length = strlen(value);
var->addOrigin(std::move(origin));
emplace(key, var);
}
void AnchoredSetVariable::resolve( void AnchoredSetVariable::resolve(
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
for (const auto& x : *this) { for (const auto& x : *this) {

View File

@ -23,6 +23,7 @@
#include "modsecurity/modsecurity.h" #include "modsecurity/modsecurity.h"
#include "modsecurity/transaction.h" #include "modsecurity/transaction.h"
#include "src/utils/regex.h" #include "src/utils/regex.h"
#include "modsecurity/string_view.hpp"
namespace modsecurity { namespace modsecurity {
@ -75,6 +76,29 @@ void AnchoredVariable::set(const std::string &a, size_t offset) {
} }
void AnchoredVariable::set(const char *a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
m_offset = offset;
m_value.assign(a, strlen(a));
origin->m_offset = offset;
origin->m_length = m_value.size();
m_var->addOrigin(std::move(origin));
}
void AnchoredVariable::set(const bpstd::string_view &a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
m_offset = offset;
m_value.assign(a.c_str(), a.size());
origin->m_offset = offset;
origin->m_length = m_value.size();
m_var->addOrigin(std::move(origin));
}
void AnchoredVariable::append(const std::string &a, size_t offset, void AnchoredVariable::append(const std::string &a, size_t offset,
bool spaceSeparator) { bool spaceSeparator) {
std::unique_ptr<VariableOrigin> origin( std::unique_ptr<VariableOrigin> origin(

View File

@ -444,12 +444,12 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t,
in.assign(newVar.c_str(), newVar.size()); in.assign(newVar.c_str(), newVar.size());
tfn->execute(t, in, out); tfn->execute(t, in, out);
newVar.assign(out.c_str(), out.size()); newVar.assign(out.c_str(), out.size());
delete tfn;
} else { } else {
ms_dbg_a(t, 1, ms_dbg_a(t, 1,
"SecRuleScript: Invalid transformation function: " \ "SecRuleScript: Invalid transformation function: " \
+ std::string(name)); + std::string(name));
} }
delete tfn;
} }
return newVar; return newVar;

View File

@ -24,8 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool BeginsWith::evaluate(Transaction *transaction, RuleWithActions *rule, bool BeginsWith::evaluate(Transaction *transaction,
const std::string &str, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
if (str.size() < p.size()) { if (str.size() < p.size()) {

View File

@ -32,7 +32,9 @@ class BeginsWith : public Operator {
explicit BeginsWith(std::unique_ptr<RunTimeString> param) explicit BeginsWith(std::unique_ptr<RunTimeString> param)
: Operator("BeginsWith", std::move(param)) { } : Operator("BeginsWith", std::move(param)) { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
}; };

View File

@ -21,10 +21,12 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool Contains::evaluate(Transaction *transaction, RuleWithActions *rule, bool Contains::evaluate(Transaction *transaction,
const std::string &input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
size_t offset = input.find(p); size_t offset = input.to_string().find(p);
bool contains = offset != std::string::npos; bool contains = offset != std::string::npos;

View File

@ -33,9 +33,11 @@ class Contains : public Operator {
public: public:
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
explicit Contains(std::unique_ptr<RunTimeString> param) explicit Contains(std::unique_ptr<RunTimeString> param)
: Operator("Contains", std::move(param)) { } : Operator("Contains", std::move(param)) { };
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
}; };

View File

@ -23,7 +23,7 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { bool ContainsWord::acceptableChar(const bpstd::string_view &a, size_t pos) {
if (a.size() - 1 < pos) { if (a.size() - 1 < pos) {
return false; return false;
} }
@ -36,37 +36,40 @@ bool ContainsWord::acceptableChar(const std::string& a, size_t pos) {
return true; return true;
} }
bool ContainsWord::evaluate(Transaction *transaction, RuleWithActions *rule, bool ContainsWord::evaluate(Transaction *transaction,
const std::string &str, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &inputView,
RuleMessage *ruleMessage) {
std::string paramTarget(m_string->evaluate(transaction)); std::string paramTarget(m_string->evaluate(transaction));
std::string input = inputView.to_string();
if (paramTarget.empty()) { if (paramTarget.empty()) {
return true; return true;
} }
if (str.empty()) { if (input.empty()) {
return false; return false;
} }
if (str == paramTarget) { if (input == paramTarget) {
return true; return true;
} }
size_t pos = str.find(paramTarget); size_t pos = input.find(paramTarget);
while (pos != std::string::npos) { while (pos != std::string::npos) {
if (pos == 0 && acceptableChar(str, paramTarget.size())) { if (pos == 0 && acceptableChar(input, paramTarget.size())) {
logOffset(ruleMessage, 0, paramTarget.size()); logOffset(ruleMessage, 0, paramTarget.size());
return true; return true;
} }
if (pos + paramTarget.size() == str.size() && if (pos + paramTarget.size() == input.size() &&
acceptableChar(str, pos - 1)) { acceptableChar(input, pos - 1)) {
logOffset(ruleMessage, pos, paramTarget.size()); logOffset(ruleMessage, pos, paramTarget.size());
return true; return true;
} }
if (acceptableChar(str, pos - 1) && if (acceptableChar(input, pos - 1) &&
acceptableChar(str, pos + paramTarget.size())) { acceptableChar(input, pos + paramTarget.size())) {
logOffset(ruleMessage, pos, paramTarget.size()); logOffset(ruleMessage, pos, paramTarget.size());
return true; return true;
} }
pos = str.find(paramTarget, pos + 1); pos = input.find(paramTarget, pos + 1);
} }
return false; return false;

View File

@ -32,12 +32,13 @@ class ContainsWord : public Operator {
explicit ContainsWord(std::unique_ptr<RunTimeString> param) explicit ContainsWord(std::unique_ptr<RunTimeString> param)
: Operator("ContainsWord", std::move(param)) { } : Operator("ContainsWord", std::move(param)) { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string &str, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
private: private:
static bool acceptableChar(const std::string& a, size_t pos); static bool acceptableChar(const bpstd::string_view &a, size_t pos);
}; };
} // namespace operators } // namespace operators

View File

@ -27,31 +27,33 @@ namespace modsecurity {
namespace operators { namespace operators {
bool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule, bool DetectSQLi::evaluate(Transaction *transaction,
const std::string& input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
char fingerprint[8]; char fingerprint[8];
int issqli; int issqli;
issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint); issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);
if (!t) { if (!transaction) {
goto tisempty; goto tisempty;
} }
if (issqli) { if (issqli) {
t->m_matched.push_back(fingerprint); transaction->m_matched.push_back(fingerprint);
ms_dbg_a(t, 4, "detected SQLi using libinjection with " \ ms_dbg_a(transaction, 4, "detected SQLi using libinjection with " \
"fingerprint '" + std::string(fingerprint) + "' at: '" + "fingerprint '" + std::string(fingerprint) + "' at: '" +
input + "'"); input.to_string() + "'");
if (rule && rule->hasCaptureAction()) { if (rule && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(fingerprint)); "0", std::string(fingerprint));
ms_dbg_a(t, 7, "Added DetectSQLi match TX.0: " + \ ms_dbg_a(transaction, 7, "Added DetectSQLi match TX.0: " + \
std::string(fingerprint)); std::string(fingerprint));
} }
} else { } else {
ms_dbg_a(t, 9, "detected SQLi: not able to find an " \ ms_dbg_a(transaction, 9, "detected SQLi: not able to find an " \
"inject on '" + input + "'"); "inject on '" + input.to_string() + "'");
} }
tisempty: tisempty:

View File

@ -32,8 +32,9 @@ class DetectSQLi : public Operator {
m_match_message.assign("detected SQLi using libinjection."); m_match_message.assign("detected SQLi using libinjection.");
} }
bool evaluate(Transaction *t, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
}; };

View File

@ -26,24 +26,26 @@ namespace modsecurity {
namespace operators { namespace operators {
bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule, bool DetectXSS::evaluate(Transaction *transaction,
const std::string& input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
int is_xss; int is_xss;
is_xss = libinjection_xss(input.c_str(), input.length()); is_xss = libinjection_xss(input.c_str(), input.length());
if (t) { if (transaction) {
if (is_xss) { if (is_xss) {
ms_dbg_a(t, 5, "detected XSS using libinjection."); ms_dbg_a(transaction, 5, "detected XSS using libinjection.");
if (rule && rule->hasCaptureAction()) { if (rule && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(input)); "0", std::string(input));
ms_dbg_a(t, 7, "Added DetectXSS match TX.0: " + \ ms_dbg_a(transaction, 7, "Added DetectXSS match TX.0: " + \
std::string(input)); std::string(input));
} }
} else { } else {
ms_dbg_a(t, 9, "libinjection was not able to " \ ms_dbg_a(transaction, 9, "libinjection was not able to " \
"find any XSS in: " + input); "find any XSS in: " + input.to_string());
} }
} }
return is_xss != 0; return is_xss != 0;

View File

@ -31,8 +31,9 @@ class DetectXSS : public Operator {
m_match_message.assign("detected XSS using libinjection."); m_match_message.assign("detected XSS using libinjection.");
} }
bool evaluate(Transaction *t, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
}; };

View File

@ -23,16 +23,18 @@ namespace modsecurity {
namespace operators { namespace operators {
bool EndsWith::evaluate(Transaction *transaction, RuleWithActions *rule, bool EndsWith::evaluate(Transaction *transaction,
const std::string &str, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
bool ret = false; bool ret = false;
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
if (str.length() >= p.length()) { if (input.length() >= p.length()) {
ret = (0 == str.compare(str.length() - p.length(), ret = (0 == input.compare(input.length() - p.length(),
p.length(), p)); p.length(), p));
if (ret) { if (ret) {
logOffset(ruleMessage, str.length() - p.length(), logOffset(ruleMessage, input.length() - p.length(),
p.size()); p.size());
} }
} }

View File

@ -33,8 +33,10 @@ class EndsWith : public Operator {
: Operator("EndsWith", std::move(param)) { : Operator("EndsWith", std::move(param)) {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
}; };

View File

@ -24,7 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Eq::evaluate(Transaction *transaction, const std::string &input) { bool Eq::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
int p = 0; int p = 0;
int i = 0; int i = 0;
std::string pt(m_string->evaluate(transaction)); std::string pt(m_string->evaluate(transaction));
@ -35,7 +38,7 @@ bool Eq::evaluate(Transaction *transaction, const std::string &input) {
p = 0; p = 0;
} }
try { try {
i = std::stoi(input); i = std::stoi(input.c_str());
} catch (...) { } catch (...) {
i = 0; i = 0;
} }

View File

@ -31,7 +31,11 @@ class Eq : public Operator {
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
explicit Eq(std::unique_ptr<RunTimeString> param) explicit Eq(std::unique_ptr<RunTimeString> param)
: Operator("Eq", std::move(param)) { } : Operator("Eq", std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &input) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -96,21 +96,24 @@ FuzzyHash::~FuzzyHash() {
} }
bool FuzzyHash::evaluate(Transaction *t, const std::string &str) { bool FuzzyHash::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
#ifdef WITH_SSDEEP #ifdef WITH_SSDEEP
char result[FUZZY_MAX_RESULT]; char result[FUZZY_MAX_RESULT];
struct fuzzy_hash_chunk *chunk = m_head; struct fuzzy_hash_chunk *chunk = m_head;
if (fuzzy_hash_buf((const unsigned char*)str.c_str(), if (fuzzy_hash_buf((const unsigned char*)str.c_str(),
str.size(), result)) { str.size(), result)) {
ms_dbg_a(t, 4, "Problems generating fuzzy hash"); ms_dbg_a(transaction, 4, "Problems generating fuzzy hash");
return false; return false;
} }
while (chunk != NULL) { while (chunk != NULL) {
int i = fuzzy_compare(chunk->data, result); int i = fuzzy_compare(chunk->data, result);
if (i >= m_threshold) { if (i >= m_threshold) {
ms_dbg_a(t, 4, "Fuzzy hash: matched " \ ms_dbg_a(transaction, 4, "Fuzzy hash: matched " \
"with score: " + std::to_string(i) + "."); "with score: " + std::to_string(i) + ".");
return true; return true;
} }

View File

@ -44,9 +44,12 @@ class FuzzyHash : public Operator {
m_head(NULL) { } m_head(NULL) { }
~FuzzyHash(); ~FuzzyHash();
bool evaluate(Transaction *transaction, const std::string &std) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
bool init(const std::string &param, std::string *error) override; bool init(const std::string &file, std::string *error) override;
private: private:
int m_threshold; int m_threshold;
struct fuzzy_hash_chunk *m_head; struct fuzzy_hash_chunk *m_head;

View File

@ -23,11 +23,13 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool Ge::evaluate(Transaction *transaction, const std::string &input) { bool Ge::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
std::string i = input;
bool ge = atoll(i.c_str()) >= atoll(p.c_str()); bool ge = atoll(str.c_str()) >= atoll(p.c_str());
return ge; return ge;
} }

View File

@ -32,7 +32,11 @@ class Ge : public Operator {
: Operator("Ge", std::move(param)) { : Operator("Ge", std::move(param)) {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, const std::string &input) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -34,16 +34,19 @@ namespace modsecurity {
namespace operators { namespace operators {
bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) { bool GeoLookup::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
using std::placeholders::_1; using std::placeholders::_1;
using std::placeholders::_2; using std::placeholders::_2;
bool ret = true; bool ret = true;
if (trans) { if (transaction) {
ret = Utils::GeoLookup::getInstance().lookup(exp, trans, ret = Utils::GeoLookup::getInstance().lookup(str.c_str(), transaction,
std::bind(&GeoLookup::debug, this, trans, _1, _2)); std::bind(&GeoLookup::debug, this, transaction, _1, _2));
} else { } else {
ret = Utils::GeoLookup::getInstance().lookup(exp, NULL, ret = Utils::GeoLookup::getInstance().lookup(str.c_str(), NULL,
nullptr); nullptr);
} }

View File

@ -29,11 +29,15 @@ class GeoLookup : public Operator {
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
GeoLookup() GeoLookup()
: Operator("GeoLookup") { } : Operator("GeoLookup") { }
bool evaluate(Transaction *transaction, const std::string &exp) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
protected: protected:
bool debug(Transaction *transaction, int x, const std::string &a) { bool debug(Transaction *transaction, int x, const bpstd::string_view &str) {
ms_dbg_a(transaction, x, a); ms_dbg_a(transaction, x, str.to_string());
return true; return true;
} }
}; };

View File

@ -23,7 +23,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool GsbLookup::evaluate(Transaction *transaction, const std::string &str) { bool GsbLookup::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
/** /**
* @todo Implement the operator GeoLookup. * @todo Implement the operator GeoLookup.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#gsblookup * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#gsblookup

View File

@ -31,7 +31,10 @@ class GsbLookup : public Operator {
explicit GsbLookup(std::unique_ptr<RunTimeString> param) explicit GsbLookup(std::unique_ptr<RunTimeString> param)
: Operator("GsbLookup", std::move(param)) { } : Operator("GsbLookup", std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &str) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -23,10 +23,13 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool Gt::evaluate(Transaction *transaction, const std::string &input) { bool Gt::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
bool gt = atoll(input.c_str()) > atoll(p.c_str()); bool gt = atoll(str.c_str()) > atoll(p.c_str());
return gt; return gt;
} }

View File

@ -33,7 +33,11 @@ class Gt : public Operator {
: Operator("Gt", std::move(param)) { : Operator("Gt", std::move(param)) {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, const std::string &input) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -49,9 +49,12 @@ bool InspectFile::init(const std::string &param2, std::string *error) {
} }
bool InspectFile::evaluate(Transaction *transaction, const std::string &str) { bool InspectFile::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
if (m_isScript) { if (m_isScript) {
return m_lua.run(transaction, str); return m_lua.run(transaction, str.c_str());
} else { } else {
FILE *in; FILE *in;
char buff[512]; char buff[512];
@ -61,7 +64,7 @@ bool InspectFile::evaluate(Transaction *transaction, const std::string &str) {
openstr.append(m_param); openstr.append(m_param);
openstr.append(" "); openstr.append(" ");
openstr.append(str); openstr.append(str.c_str());
if (!(in = popen(openstr.c_str(), "r"))) { if (!(in = popen(openstr.c_str(), "r"))) {
return false; return false;
} }

View File

@ -35,8 +35,13 @@ class InspectFile : public Operator {
m_file(""), m_file(""),
m_isScript(false) { } m_isScript(false) { }
bool init(const std::string &param, std::string *error) override; bool init(const std::string &file, std::string *error) override;
bool evaluate(Transaction *transaction, const std::string &str) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
private: private:
std::string m_file; std::string m_file;
bool m_isScript; bool m_isScript;

View File

@ -37,8 +37,11 @@ bool IpMatch::init(const std::string &file, std::string *error) {
} }
bool IpMatch::evaluate(Transaction *transaction, const std::string &input) { bool IpMatch::evaluate(Transaction *transaction,
return m_tree.contains(input); RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
return m_tree.contains(str.c_str());
} }

View File

@ -34,7 +34,10 @@ class IpMatch : public Operator {
IpMatch(const std::string &n, std::unique_ptr<RunTimeString> param) IpMatch(const std::string &n, std::unique_ptr<RunTimeString> param)
: Operator(n, std::move(param)) { } : Operator(n, std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &input) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
bool init(const std::string &file, std::string *error) override; bool init(const std::string &file, std::string *error) override;

View File

@ -23,10 +23,13 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool Le::evaluate(Transaction *transaction, const std::string &input) { bool Le::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
bool le = atoll(input.c_str()) <= atoll(p.c_str()); bool le = atoll(str.c_str()) <= atoll(p.c_str());
return le; return le;
} }

View File

@ -34,7 +34,10 @@ class Le : public Operator {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, const std::string &input) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };

View File

@ -22,10 +22,13 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool Lt::evaluate(Transaction *transaction, const std::string &input) { bool Lt::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
bool lt = atoll(input.c_str()) < atoll(p.c_str()); bool lt = atoll(str.c_str()) < atoll(p.c_str());
return lt; return lt;
} }

View File

@ -34,7 +34,10 @@ class Lt : public Operator {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, const std::string &input) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -20,7 +20,10 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool NoMatch::evaluate(Transaction *transaction, const std::string &str) { bool NoMatch::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
return false; return false;
} }

View File

@ -32,7 +32,10 @@ class NoMatch : public Operator {
NoMatch() NoMatch()
: Operator("NoMatch") { } : Operator("NoMatch") { }
bool evaluate(Transaction *transaction, const std::string &str) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -71,7 +71,7 @@ namespace operators {
bool Operator::evaluateInternal(Transaction *transaction, bool Operator::evaluateInternal(Transaction *transaction,
RuleWithActions *rule, const std::string& a, RuleMessage *rm) { RuleWithActions *rule, const bpstd::string_view &a, RuleMessage *rm) {
bool res = evaluate(transaction, rule, a, rm); bool res = evaluate(transaction, rule, a, rm);
if (m_negation) { if (m_negation) {
@ -81,28 +81,6 @@ bool Operator::evaluateInternal(Transaction *transaction,
return res; return res;
} }
bool Operator::evaluateInternal(Transaction *transaction,
RuleWithActions *rule, const std::string& a) {
bool res = evaluate(transaction, rule, a);
if (m_negation) {
return !res;
}
return res;
}
bool Operator::evaluateInternal(Transaction *transaction,
const std::string& a) {
bool res = evaluate(transaction, a);
if (m_negation) {
return !res;
}
return res;
}
std::string Operator::resolveMatchMessage(Transaction *t, std::string Operator::resolveMatchMessage(Transaction *t,
std::string key, std::string value) { std::string key, std::string value) {
@ -132,7 +110,10 @@ std::string Operator::resolveMatchMessage(Transaction *t,
} }
bool Operator::evaluate(Transaction *transaction, const std::string& a) { bool Operator::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
ms_dbg_a(transaction, 2, "Operator: " + m_op + \ ms_dbg_a(transaction, 2, "Operator: " + m_op + \
" is not implemented or malfunctioning."); " is not implemented or malfunctioning.");
return true; return true;

View File

@ -24,6 +24,7 @@
#include "modsecurity/rule.h" #include "modsecurity/rule.h"
#include "modsecurity/rule_message.h" #include "modsecurity/rule_message.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "modsecurity/string_view.hpp"
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
@ -107,26 +108,17 @@ class Operator {
return true; return true;
} }
virtual std::string resolveMatchMessage(Transaction *t, bool evaluateInternal(Transaction *transaction,
std::string key, std::string value); RuleWithActions *rule,
const bpstd::string_view& a,
RuleMessage *ruleMessage);
bool evaluateInternal(Transaction *t, const std::string& a); virtual bool evaluate(Transaction *transaction,
bool evaluateInternal(Transaction *t, RuleWithActions *rule, RuleWithActions *rule,
const std::string& a); const bpstd::string_view &str,
bool evaluateInternal(Transaction *t, RuleWithActions *rule, RuleMessage *ruleMessage);
const std::string& a, RuleMessage *ruleMessage);
virtual bool evaluate(Transaction *transaction, const std::string &str);
virtual bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str) {
return evaluate(transaction, str);
}
virtual bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, RuleMessage *ruleMessage) {
return evaluate(transaction, str);
}
static void logOffset(RuleMessage *ruleMessage, int offset, int len) { static void logOffset(RuleMessage *ruleMessage, int offset, int len) {
if (ruleMessage) { if (ruleMessage) {
ruleMessage->m_reference.append("o" ruleMessage->m_reference.append("o"
@ -135,6 +127,10 @@ class Operator {
} }
} }
virtual std::string resolveMatchMessage(Transaction *t,
std::string key, std::string value);
std::string m_match_message; std::string m_match_message;
bool m_negation; bool m_negation;
std::string m_op; std::string m_op;

View File

@ -83,8 +83,10 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
} }
bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, bool Pm::evaluate(Transaction *transaction,
const std::string &input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
int rc = -1; int rc = -1;
ACMPT pt; ACMPT pt;
pt.parser = m_p; pt.parser = m_p;
@ -93,7 +95,7 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
#ifdef MODSEC_MUTEX_ON_PM #ifdef MODSEC_MUTEX_ON_PM
pthread_mutex_lock(&m_lock); pthread_mutex_lock(&m_lock);
#endif #endif
rc = acmp_process_quick(&pt, &match, input.c_str(), input.length()); rc = acmp_process_quick(&pt, &match, str.c_str(), str.length());
#ifdef MODSEC_MUTEX_ON_PM #ifdef MODSEC_MUTEX_ON_PM
pthread_mutex_unlock(&m_lock); pthread_mutex_unlock(&m_lock);
#endif #endif

View File

@ -41,8 +41,10 @@ class Pm : public Operator {
m_p = acmp_create(0); m_p = acmp_create(0);
} }
~Pm(); ~Pm();
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;

View File

@ -56,7 +56,7 @@ bool PmFromFile::init(const std::string &config, std::string *error) {
iss = new std::stringstream(client.content); iss = new std::stringstream(client.content);
} else { } else {
std::string err; std::string err;
std::string resource = utils::find_resource(m_param, config, &err); std::string resource = utils::find_resource(m_param, config.c_str(), &err);
iss = new std::ifstream(resource, std::ios::in); iss = new std::ifstream(resource, std::ios::in);
if (((std::ifstream *)iss)->is_open() == false) { if (((std::ifstream *)iss)->is_open() == false) {

View File

@ -202,11 +202,12 @@ void Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr,
} }
bool Rbl::evaluate(Transaction *t, RuleWithActions *rule, bool Rbl::evaluate(Transaction *transaction,
const std::string& ipStr, RuleWithActions *rule,
RuleMessage *ruleMessage) { const bpstd::string_view &str,
RuleMessage *ruleMessage) {
struct addrinfo *info = NULL; struct addrinfo *info = NULL;
std::string host = Rbl::mapIpToAddress(ipStr, t); std::string host = Rbl::mapIpToAddress(str.c_str(), transaction);
int rc = 0; int rc = 0;
if (host.empty()) { if (host.empty()) {
@ -219,20 +220,20 @@ bool Rbl::evaluate(Transaction *t, RuleWithActions *rule,
if (info != NULL) { if (info != NULL) {
freeaddrinfo(info); freeaddrinfo(info);
} }
ms_dbg_a(t, 5, "RBL lookup of " + ipStr + " failed."); ms_dbg_a(transaction, 5, "RBL lookup of " + str.to_string() + " failed.");
return false; return false;
} }
struct sockaddr *addr = info->ai_addr; struct sockaddr *addr = info->ai_addr;
struct sockaddr_in *sin = (struct sockaddr_in *) addr; struct sockaddr_in *sin = (struct sockaddr_in *) addr;
furtherInfo(sin, ipStr, t, m_provider); furtherInfo(sin, str.c_str(), transaction, m_provider);
freeaddrinfo(info); freeaddrinfo(info);
if (rule && t && rule->hasCaptureAction()) { if (rule && transaction && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(ipStr)); "0", std::string(str));
ms_dbg_a(t, 7, "Added RXL match TX.0: " + \ ms_dbg_a(transaction, 7, "Added RXL match TX.0: " + \
std::string(ipStr)); std::string(str));
} }
return true; return true;

View File

@ -76,8 +76,10 @@ class Rbl : public Operator {
m_provider = RblProvider::httpbl; m_provider = RblProvider::httpbl;
} }
} }
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input, bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const; std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const;

View File

@ -23,7 +23,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Rsub::evaluate(Transaction *transaction, const std::string &str) { bool Rsub::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
/** /**
* @todo Implement the operator Rsub. * @todo Implement the operator Rsub.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#rsub * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#rsub

View File

@ -32,7 +32,11 @@ class Rsub : public Operator {
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
explicit Rsub(std::unique_ptr<RunTimeString> param) explicit Rsub(std::unique_ptr<RunTimeString> param)
: Operator("Rsub", std::move(param)) { } : Operator("Rsub", std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &str) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };

View File

@ -29,7 +29,7 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Rx::init(const std::string &arg, std::string *error) { bool Rx::init(const std::string &file, std::string *error) {
if (m_string->m_containsMacro == false) { if (m_string->m_containsMacro == false) {
m_re = new Regex(m_param); m_re = new Regex(m_param);
} }
@ -38,8 +38,10 @@ bool Rx::init(const std::string &arg, std::string *error) {
} }
bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, bool Rx::evaluate(Transaction *transaction,
const std::string& input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
Regex *re; Regex *re;
if (m_param.empty() && !m_string->m_containsMacro) { if (m_param.empty() && !m_string->m_containsMacro) {
@ -54,8 +56,8 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule,
} }
std::vector<Utils::SMatchCapture> captures; std::vector<Utils::SMatchCapture> captures;
re->searchOneMatch(input, captures); // FIXME: searchOneMatch should accept string_view.
re->searchOneMatch(input.c_str(), captures);
if (rule && rule->hasCaptureAction() && transaction) { if (rule && rule->hasCaptureAction() && transaction) {
for (const Utils::SMatchCapture& capture : captures) { for (const Utils::SMatchCapture& capture : captures) {
const std::string capture_substring(input.substr(capture.m_offset,capture.m_length)); const std::string capture_substring(input.substr(capture.m_offset,capture.m_length));

View File

@ -49,11 +49,12 @@ class Rx : public Operator {
} }
} }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
bool init(const std::string &arg, std::string *error) override; bool init(const std::string &file, std::string *error) override;
private: private:
Regex *m_re; Regex *m_re;

View File

@ -37,7 +37,7 @@ bool RxGlobal::init(const std::string &arg, std::string *error) {
bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule, bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input, RuleMessage *ruleMessage) { const bpstd::string_view& input, RuleMessage *ruleMessage) {
Regex *re; Regex *re;
if (m_param.empty() && !m_string->m_containsMacro) { if (m_param.empty() && !m_string->m_containsMacro) {
@ -52,7 +52,7 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,
} }
std::vector<Utils::SMatchCapture> captures; std::vector<Utils::SMatchCapture> captures;
re->searchGlobal(input, captures); re->searchGlobal(input.c_str(), captures);
if (rule && rule->hasCaptureAction() && transaction) { if (rule && rule->hasCaptureAction() && transaction) {
for (const Utils::SMatchCapture& capture : captures) { for (const Utils::SMatchCapture& capture : captures) {

View File

@ -50,7 +50,7 @@ class RxGlobal : public Operator {
} }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string& input, const bpstd::string_view& input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
bool init(const std::string &arg, std::string *error) override; bool init(const std::string &arg, std::string *error) override;

View File

@ -20,9 +20,12 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool StrEq::evaluate(Transaction *transaction, const std::string &str) { bool StrEq::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string pt(m_string->evaluate(transaction)); std::string pt(m_string->evaluate(transaction));
return !pt.compare(str); return !pt.compare(str.to_string());
} }

View File

@ -34,7 +34,10 @@ class StrEq : public Operator {
explicit StrEq(std::unique_ptr<RunTimeString> param) explicit StrEq(std::unique_ptr<RunTimeString> param)
: Operator("StrEq", std::move(param)) { } : Operator("StrEq", std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &str) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -24,9 +24,12 @@ namespace modsecurity {
namespace operators { namespace operators {
bool StrMatch::evaluate(Transaction *transaction, const std::string &input) { bool StrMatch::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
std::string p(m_string->evaluate(transaction)); std::string p(m_string->evaluate(transaction));
bool ret = input.find(p) != std::string::npos; bool ret = str.find(p) != std::string::npos;
return ret; return ret;
} }

View File

@ -34,7 +34,10 @@ class StrMatch : public Operator {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, const std::string &input) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -19,7 +19,9 @@ namespace modsecurity {
namespace operators { namespace operators {
bool UnconditionalMatch::evaluate(Transaction *transaction, bool UnconditionalMatch::evaluate(Transaction *transaction,
const std::string &input) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
return true; return true;
} }

View File

@ -31,7 +31,10 @@ class UnconditionalMatch : public Operator {
UnconditionalMatch() UnconditionalMatch()
: Operator("UnconditionalMatch") { } : Operator("UnconditionalMatch") { }
bool evaluate(Transaction *transaction, const std::string &exp) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -23,7 +23,7 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool ValidateByteRange::getRange(const std::string &rangeRepresentation, bool ValidateByteRange::getRange(const bpstd::string_view &rangeRepresentation,
std::string *error) { std::string *error) {
size_t pos = rangeRepresentation.find_first_of("-"); size_t pos = rangeRepresentation.find_first_of("-");
int start; int start;
@ -31,9 +31,10 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
if (pos == std::string::npos) { if (pos == std::string::npos) {
try { try {
start = std::stoi(rangeRepresentation); start = std::stoi(rangeRepresentation.c_str());
} catch(...) { } catch(...) {
error->assign("Not able to convert '" + rangeRepresentation + error->assign("Not able to convert '" + \
rangeRepresentation.to_string() +
"' into a number"); "' into a number");
return false; return false;
} }
@ -42,19 +43,19 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
} }
try { try {
start = std::stoi(std::string(rangeRepresentation, 0, pos)); start = std::stoi(std::string(rangeRepresentation.c_str(), 0, pos));
} catch (...) { } catch (...) {
error->assign("Not able to convert '" + error->assign("Not able to convert '" +
std::string(rangeRepresentation, 0, pos) + std::string(rangeRepresentation.c_str(), 0, pos) +
"' into a number"); "' into a number");
return false; return false;
} }
try { try {
end = std::stoi(std::string(rangeRepresentation, pos + 1, end = std::stoi(std::string(rangeRepresentation.c_str(), pos + 1,
rangeRepresentation.length() - (pos + 1))); rangeRepresentation.length() - (pos + 1)));
} catch (...) { } catch (...) {
error->assign("Not able to convert '" + std::string(rangeRepresentation, error->assign("Not able to convert '" + std::string(rangeRepresentation.c_str(),
pos + 1, rangeRepresentation.length() - (pos + 1)) + pos + 1, rangeRepresentation.length() - (pos + 1)) +
"' into a number"); "' into a number");
return false; return false;
@ -110,16 +111,18 @@ bool ValidateByteRange::init(const std::string &file,
} }
bool ValidateByteRange::evaluate(Transaction *transaction, RuleWithActions *rule, bool ValidateByteRange::evaluate(Transaction *transaction,
const std::string &input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
bool ret = true; bool ret = true;
size_t count = 0; size_t count = 0;
for (int i = 0; i < input.length(); i++) { for (int i = 0; i < str.length(); i++) {
int x = (unsigned char) input.at(i); int x = (unsigned char) str.at(i);
if (!(table[x >> 3] & (1 << (x & 0x7)))) { if (!(table[x >> 3] & (1 << (x & 0x7)))) {
// debug(9, "Value " + std::to_string(x) + " in " + // debug(9, "Value " + std::to_string(x) + " in " +
// input + " ouside range: " + param); // str + " ouside range: " + param);
logOffset(ruleMessage, i, 1); logOffset(ruleMessage, i, 1);
count++; count++;
} }

View File

@ -37,10 +37,12 @@ class ValidateByteRange : public Operator {
} }
~ValidateByteRange() override { } ~ValidateByteRange() override { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string &input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
bool getRange(const std::string &rangeRepresentation, std::string *error);
bool getRange(const bpstd::string_view &rangeRepresentation, std::string *error);
bool init(const std::string& file, std::string *error) override; bool init(const std::string& file, std::string *error) override;
private: private:
std::vector<std::string> ranges; std::vector<std::string> ranges;

View File

@ -43,25 +43,28 @@ bool ValidateDTD::init(const std::string &file, std::string *error) {
} }
bool ValidateDTD::evaluate(Transaction *t, const std::string &str) { bool ValidateDTD::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
xmlValidCtxtPtr cvp; xmlValidCtxtPtr cvp;
m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str()); m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str());
if (m_dtd == NULL) { if (m_dtd == NULL) {
std::string err = std::string("XML: Failed to load DTD: ") \ std::string err = std::string("XML: Failed to load DTD: ") \
+ m_resource; + m_resource;
ms_dbg_a(t, 4, err); ms_dbg_a(transaction, 4, err);
return true; return true;
} }
if (t->m_xml->m_data.doc == NULL) { if (transaction->m_xml->m_data.doc == NULL) {
ms_dbg_a(t, 4, "XML document tree could not "\ ms_dbg_a(transaction, 4, "XML document tree could not "\
"be found for DTD validation."); "be found for DTD validation.");
return true; return true;
} }
if (t->m_xml->m_data.well_formed != 1) { if (transaction->m_xml->m_data.well_formed != 1) {
ms_dbg_a(t, 4, "XML: DTD validation failed because " \ ms_dbg_a(transaction, 4, "XML: DTD validation failed because " \
"content is not well formed."); "content is not well formed.");
return true; return true;
} }
@ -78,22 +81,23 @@ bool ValidateDTD::evaluate(Transaction *t, const std::string &str) {
cvp = xmlNewValidCtxt(); cvp = xmlNewValidCtxt();
if (cvp == NULL) { if (cvp == NULL) {
ms_dbg_a(t, 4, "XML: Failed to create a validation context."); ms_dbg_a(transaction, 4,
"XML: Failed to create a validation context.");
return true; return true;
} }
/* Send validator errors/warnings to msr_log */ /* Send validator errors/warnings to msr_log */
cvp->error = (xmlSchemaValidityErrorFunc)error_runtime; cvp->error = (xmlSchemaValidityErrorFunc)error_runtime;
cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime; cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime;
cvp->userData = t; cvp->userData = transaction;
if (!xmlValidateDtd(cvp, t->m_xml->m_data.doc, m_dtd)) { if (!xmlValidateDtd(cvp, transaction->m_xml->m_data.doc, m_dtd)) {
ms_dbg_a(t, 4, "XML: DTD validation failed."); ms_dbg_a(transaction, 4, "XML: DTD validation failed.");
xmlFreeValidCtxt(cvp); xmlFreeValidCtxt(cvp);
return true; return true;
} }
ms_dbg_a(t, 4, std::string("XML: Successfully validated " \ ms_dbg_a(transaction, 4, std::string("XML: Successfully validated " \
"payload against DTD: ") + m_resource); "payload against DTD: ") + m_resource);
xmlFreeValidCtxt(cvp); xmlFreeValidCtxt(cvp);

View File

@ -46,7 +46,11 @@ class ValidateDTD : public Operator {
} }
} }
bool evaluate(Transaction *transaction, const std::string &str) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
bool init(const std::string &file, std::string *error) override; bool init(const std::string &file, std::string *error) override;

View File

@ -22,7 +22,10 @@
namespace modsecurity { namespace modsecurity {
namespace operators { namespace operators {
bool ValidateHash::evaluate(Transaction *transaction, const std::string &str) { bool ValidateHash::evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
/** /**
* @todo Implement the operator ValidateHash. * @todo Implement the operator ValidateHash.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateHash * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateHash

View File

@ -31,7 +31,11 @@ class ValidateHash : public Operator {
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
explicit ValidateHash(std::unique_ptr<RunTimeString> param) explicit ValidateHash(std::unique_ptr<RunTimeString> param)
: Operator("ValidateHash", std::move(param)) { } : Operator("ValidateHash", std::move(param)) { }
bool evaluate(Transaction *transaction, const std::string &str) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -39,8 +39,10 @@ bool ValidateSchema::init(const std::string &file, std::string *error) {
} }
bool ValidateSchema::evaluate(Transaction *t, bool ValidateSchema::evaluate(Transaction *transaction,
const std::string &str) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
int rc; int rc;
m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str());
@ -52,7 +54,7 @@ bool ValidateSchema::evaluate(Transaction *t,
if (m_err.empty() == false) { if (m_err.empty() == false) {
err << m_err; err << m_err;
} }
ms_dbg_a(t, 4, err.str()); ms_dbg_a(transaction, 4, err.str());
return true; return true;
} }
@ -75,7 +77,7 @@ bool ValidateSchema::evaluate(Transaction *t,
if (m_err.empty() == false) { if (m_err.empty() == false) {
err << " " << m_err; err << " " << m_err;
} }
ms_dbg_a(t, 4, err.str()); ms_dbg_a(transaction, 4, err.str());
xmlSchemaFreeParserCtxt(m_parserCtx); xmlSchemaFreeParserCtxt(m_parserCtx);
return true; return true;
} }
@ -86,23 +88,23 @@ bool ValidateSchema::evaluate(Transaction *t,
if (m_err.empty() == false) { if (m_err.empty() == false) {
err << " " << m_err; err << " " << m_err;
} }
ms_dbg_a(t, 4, err.str()); ms_dbg_a(transaction, 4, err.str());
return true; return true;
} }
/* Send validator errors/warnings to msr_log */ /* Send validator errors/warnings to msr_log */
xmlSchemaSetValidErrors(m_validCtx, xmlSchemaSetValidErrors(m_validCtx,
(xmlSchemaValidityErrorFunc)error_runtime, (xmlSchemaValidityErrorFunc)error_runtime,
(xmlSchemaValidityWarningFunc)warn_runtime, t); (xmlSchemaValidityWarningFunc)warn_runtime, transaction);
if (t->m_xml->m_data.doc == NULL) { if (transaction->m_xml->m_data.doc == NULL) {
ms_dbg_a(t, 4, "XML document tree could not be found for " \ ms_dbg_a(transaction, 4, "XML document tree could not be found for " \
"schema validation."); "schema validation.");
return true; return true;
} }
if (t->m_xml->m_data.well_formed != 1) { if (transaction->m_xml->m_data.well_formed != 1) {
ms_dbg_a(t, 4, "XML: Schema validation failed because " \ ms_dbg_a(transaction, 4, "XML: Schema validation failed because " \
"content is not well formed."); "content is not well formed.");
return true; return true;
} }
@ -116,15 +118,15 @@ bool ValidateSchema::evaluate(Transaction *t,
} }
*/ */
rc = xmlSchemaValidateDoc(m_validCtx, t->m_xml->m_data.doc); rc = xmlSchemaValidateDoc(m_validCtx, transaction->m_xml->m_data.doc);
if (rc != 0) { if (rc != 0) {
ms_dbg_a(t, 4, "XML: Schema validation failed."); ms_dbg_a(transaction, 4, "XML: Schema validation failed.");
xmlSchemaFree(m_schema); xmlSchemaFree(m_schema);
xmlSchemaFreeParserCtxt(m_parserCtx); xmlSchemaFreeParserCtxt(m_parserCtx);
return true; /* No match. */ return true; /* No match. */
} }
ms_dbg_a(t, 4, "XML: Successfully validated payload against " \ ms_dbg_a(transaction, 4, "XML: Successfully validated payload against " \
"Schema: " + m_resource); "Schema: " + m_resource);
xmlSchemaFree(m_schema); xmlSchemaFree(m_schema);
xmlSchemaFreeParserCtxt(m_parserCtx); xmlSchemaFreeParserCtxt(m_parserCtx);

View File

@ -58,7 +58,11 @@ class ValidateSchema : public Operator {
} }
} }
bool evaluate(Transaction *transaction, const std::string &str) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
bool init(const std::string &file, std::string *error) override; bool init(const std::string &file, std::string *error) override;

View File

@ -68,8 +68,10 @@ int ValidateUrlEncoding::validate_url_encoding(const char *input,
} }
bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *rule, bool ValidateUrlEncoding::evaluate(Transaction *transaction,
const std::string &input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
size_t offset = 0; size_t offset = 0;
bool res = false; bool res = false;
@ -82,14 +84,15 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru
case 1 : case 1 :
/* Encoding is valid */ /* Encoding is valid */
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 7, "Valid URL Encoding at '" +input + "'"); ms_dbg_a(transaction, 7, "Valid URL Encoding at '" + \
input.to_string() + "'");
} }
res = false; res = false;
break; break;
case -2 : case -2 :
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 7, "Invalid URL Encoding: Non-hexadecimal " ms_dbg_a(transaction, 7, "Invalid URL Encoding: Non-hexadecimal "
"digits used at '" + input + "'"); "digits used at '" + input.to_string() + "'");
logOffset(ruleMessage, offset, input.size()); logOffset(ruleMessage, offset, input.size());
} }
res = true; /* Invalid match. */ res = true; /* Invalid match. */
@ -97,7 +100,7 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru
case -3 : case -3 :
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 7, "Invalid URL Encoding: Not enough " \ ms_dbg_a(transaction, 7, "Invalid URL Encoding: Not enough " \
"characters at the end of input at '" + input + "'"); "characters at the end of input at '" + input.to_string() + "'");
logOffset(ruleMessage, offset, input.size()); logOffset(ruleMessage, offset, input.size());
} }
res = true; /* Invalid match. */ res = true; /* Invalid match. */
@ -107,7 +110,7 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 7, "Invalid URL Encoding: Internal " \ ms_dbg_a(transaction, 7, "Invalid URL Encoding: Internal " \
"Error (rc = " + std::to_string(rc) + ") at '" + "Error (rc = " + std::to_string(rc) + ") at '" +
input + "'"); input.to_string() + "'");
logOffset(ruleMessage, offset, input.size()); logOffset(ruleMessage, offset, input.size());
} }
res = true; res = true;

View File

@ -31,8 +31,9 @@ class ValidateUrlEncoding : public Operator {
ValidateUrlEncoding() ValidateUrlEncoding()
: Operator("ValidateUrlEncoding") { } : Operator("ValidateUrlEncoding") { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string &input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
static int validate_url_encoding(const char *input, uint64_t input_length, static int validate_url_encoding(const char *input, uint64_t input_length,

View File

@ -113,8 +113,10 @@ int ValidateUtf8Encoding::detect_utf8_character(
return unicode_len; return unicode_len;
} }
bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *rule, bool ValidateUtf8Encoding::evaluate(Transaction *transaction,
const std::string &str, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
unsigned int i, bytes_left; unsigned int i, bytes_left;
const char *str_c = str.c_str(); const char *str_c = str.c_str();
@ -128,7 +130,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: "
"not enough bytes in character " "not enough bytes in character "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
} }
return true; return true;
@ -137,7 +139,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: "
"invalid byte value in character " "invalid byte value in character "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
logOffset(ruleMessage, i, str.size()); logOffset(ruleMessage, i, str.size());
} }
@ -147,7 +149,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: "
"overlong character detected " "overlong character detected "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
logOffset(ruleMessage, i, str.size()); logOffset(ruleMessage, i, str.size());
} }
@ -157,7 +159,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: "
"use of restricted character " "use of restricted character "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
logOffset(ruleMessage, i, str.size()); logOffset(ruleMessage, i, str.size());
} }
@ -166,7 +168,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
case UNICODE_ERROR_DECODING_ERROR : case UNICODE_ERROR_DECODING_ERROR :
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Error validating UTF-8 decoding " ms_dbg_a(transaction, 8, "Error validating UTF-8 decoding "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
logOffset(ruleMessage, i, str.size()); logOffset(ruleMessage, i, str.size());
} }
@ -177,7 +179,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r
if (rc <= 0) { if (rc <= 0) {
if (transaction) { if (transaction) {
ms_dbg_a(transaction, 8, "Internal error during UTF-8 validation " ms_dbg_a(transaction, 8, "Internal error during UTF-8 validation "
"at " + str + ". [offset \"" + "at " + str.to_string() + ". [offset \"" +
std::to_string(i) + "\"]"); std::to_string(i) + "\"]");
logOffset(ruleMessage, i, str.size()); logOffset(ruleMessage, i, str.size());
} }

View File

@ -38,8 +38,9 @@ class ValidateUtf8Encoding : public Operator {
ValidateUtf8Encoding() ValidateUtf8Encoding()
: Operator("ValidateUtf8Encoding") { } : Operator("ValidateUtf8Encoding") { }
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string &str, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
static int detect_utf8_character(const unsigned char *p_read, static int detect_utf8_character(const unsigned char *p_read,

View File

@ -119,8 +119,10 @@ bool VerifyCC::init(const std::string &param2, std::string *error) {
} }
bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, bool VerifyCC::evaluate(Transaction *transaction,
const std::string& i, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &i,
RuleMessage *ruleMessage) {
int offset = 0; int offset = 0;
int target_length = i.length(); int target_length = i.length();
@ -139,18 +141,18 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
return false; return false;
} }
if (ret > 0) { if (ret > 0) {
match = std::string(i, ovector[0], ovector[1] - ovector[0]); match = std::string(i.to_string(), ovector[0], ovector[1] - ovector[0]);
int is_cc = luhnVerify(match.c_str(), match.size()); int is_cc = luhnVerify(match.c_str(), match.size());
if (is_cc) { if (is_cc) {
if (t) { if (transaction) {
if (rule && rule->hasCaptureAction()) { if (rule && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", std::string(match)); "0", std::string(match));
ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + \ ms_dbg_a(transaction, 7, "Added VerifyCC match TX.0: " + \
std::string(match)); std::string(match));
} }
ms_dbg_a(t, 9, "CC# match \"" + m_param + ms_dbg_a(transaction, 9, "CC# match \"" + m_param +
"\" at " + i + ". [offset " + "\" at " + i.to_string() + ". [offset " +
std::to_string(offset) + "]"); std::to_string(offset) + "]");
} }
return true; return true;

View File

@ -35,10 +35,13 @@ class VerifyCC : public Operator {
m_pce(NULL) { } m_pce(NULL) { }
~VerifyCC(); ~VerifyCC();
bool evaluate(Transaction *t, RuleWithActions *rule,
const std::string& input,
RuleMessage *ruleMessage) override;
bool init(const std::string &param, std::string *error) override; bool init(const std::string &param, std::string *error) override;
bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
private: private:
pcre *m_pc; pcre *m_pc;
pcre_extra *m_pce; pcre_extra *m_pce;

View File

@ -110,8 +110,10 @@ bool VerifyCPF::verify(const char *cpfnumber, int len) {
} }
bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule, bool VerifyCPF::evaluate(Transaction *transaction,
const std::string& input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
std::list<SMatch> matches; std::list<SMatch> matches;
bool is_cpf = false; bool is_cpf = false;
int i; int i;
@ -121,15 +123,15 @@ bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule,
} }
for (i = 0; i < input.size() - 1 && is_cpf == false; i++) { for (i = 0; i < input.size() - 1 && is_cpf == false; i++) {
matches = m_re->searchAll(input.substr(i, input.size())); matches = m_re->searchAll(input.substr(i, input.size()).to_string());
for (const auto & m : matches) { for (const auto & m : matches) {
is_cpf = verify(m.str().c_str(), m.str().size()); is_cpf = verify(m.str().c_str(), m.str().size());
if (is_cpf) { if (is_cpf) {
logOffset(ruleMessage, m.offset(), m.str().size()); logOffset(ruleMessage, m.offset(), m.str().size());
if (rule && t && rule->hasCaptureAction()) { if (rule && transaction && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", m.str()); "0", m.str());
ms_dbg_a(t, 7, "Added VerifyCPF match TX.0: " + \ ms_dbg_a(transaction, 7, "Added VerifyCPF match TX.0: " + \
m.str()); m.str());
} }

View File

@ -46,8 +46,9 @@ class VerifyCPF : public Operator {
bool operator=(const VerifyCPF &a) = delete; bool operator=(const VerifyCPF &a) = delete;
VerifyCPF(const VerifyCPF &a) = delete; VerifyCPF(const VerifyCPF &a) = delete;
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
bool verify(const char *ssnumber, int len); bool verify(const char *ssnumber, int len);

View File

@ -112,8 +112,10 @@ invalid:
} }
bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule, bool VerifySSN::evaluate(Transaction *transaction,
const std::string& input, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) {
std::list<SMatch> matches; std::list<SMatch> matches;
bool is_ssn = false; bool is_ssn = false;
int i; int i;
@ -123,15 +125,15 @@ bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule,
} }
for (i = 0; i < input.size() - 1 && is_ssn == false; i++) { for (i = 0; i < input.size() - 1 && is_ssn == false; i++) {
matches = m_re->searchAll(input.substr(i, input.size())); matches = m_re->searchAll(input.substr(i, input.size()).to_string());
for (const auto & j : matches) { for (const auto & j : matches) {
is_ssn = verify(j.str().c_str(), j.str().size()); is_ssn = verify(j.str().c_str(), j.str().size());
if (is_ssn) { if (is_ssn) {
logOffset(ruleMessage, j.offset(), j.str().size()); logOffset(ruleMessage, j.offset(), j.str().size());
if (rule && t && rule->hasCaptureAction()) { if (rule && transaction && rule->hasCaptureAction()) {
t->m_collections.m_tx_collection->storeOrUpdateFirst( transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
"0", j.str()); "0", j.str());
ms_dbg_a(t, 7, "Added VerifySSN match TX.0: " + \ ms_dbg_a(transaction, 7, "Added VerifySSN match TX.0: " + \
j.str()); j.str());
} }

View File

@ -46,8 +46,9 @@ class VerifySSN : public Operator {
bool operator=(const VerifySSN &a) = delete; bool operator=(const VerifySSN &a) = delete;
VerifySSN(const VerifySSN &a) = delete; VerifySSN(const VerifySSN &a) = delete;
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;

View File

@ -78,8 +78,10 @@ bool VerifySVNR::verify(const char *svnrnumber, int len) {
} }
bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule, bool VerifySVNR::evaluate(Transaction *t,
const std::string& input, RuleMessage* ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage* ruleMessage) {
std::list<SMatch> matches; std::list<SMatch> matches;
bool is_svnr = false; bool is_svnr = false;
int i; int i;
@ -89,7 +91,7 @@ bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule,
} }
for (i = 0; i < input.size() - 1 && is_svnr == false; i++) { for (i = 0; i < input.size() - 1 && is_svnr == false; i++) {
matches = m_re->searchAll(input.substr(i, input.size())); matches = m_re->searchAll(input.substr(i, input.size()).to_string());
for (const auto & j : matches) { for (const auto & j : matches) {
is_svnr = verify(j.str().c_str(), j.str().size()); is_svnr = verify(j.str().c_str(), j.str().size());

View File

@ -32,8 +32,9 @@ class VerifySVNR : public Operator {
bool operator=(const VerifySVNR &a) = delete; bool operator=(const VerifySVNR &a) = delete;
VerifySVNR(const VerifySVNR &a) = delete; VerifySVNR(const VerifySVNR &a) = delete;
bool evaluate(Transaction *transaction, RuleWithActions *rule, bool evaluate(Transaction *transaction,
const std::string& input, RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override; RuleMessage *ruleMessage) override;
bool verify(const char *ssnumber, int len); bool verify(const char *ssnumber, int len);

View File

@ -24,8 +24,10 @@ namespace modsecurity {
namespace operators { namespace operators {
bool Within::evaluate(Transaction *transaction, RuleWithActions *rule, bool Within::evaluate(Transaction *transaction,
const std::string &str, RuleMessage *ruleMessage) { RuleWithActions *rule,
const bpstd::string_view &str,
RuleMessage *ruleMessage) {
bool res = false; bool res = false;
size_t pos = 0; size_t pos = 0;
std::string paramTarget(m_string->evaluate(transaction)); std::string paramTarget(m_string->evaluate(transaction));
@ -34,7 +36,7 @@ bool Within::evaluate(Transaction *transaction, RuleWithActions *rule,
return true; return true;
} }
pos = paramTarget.find(str); pos = paramTarget.find(str.c_str());
res = pos != std::string::npos; res = pos != std::string::npos;
if (res) { if (res) {
logOffset(ruleMessage, pos, str.size()); logOffset(ruleMessage, pos, str.size());

View File

@ -33,8 +33,11 @@ class Within : public Operator {
: Operator("Within", std::move(param)) { : Operator("Within", std::move(param)) {
m_couldContainsMacro = true; m_couldContainsMacro = true;
} }
bool evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &str, RuleMessage *ruleMessage) override; bool evaluate(Transaction *transaction,
RuleWithActions *rule,
const bpstd::string_view &input,
RuleMessage *ruleMessage) override;
}; };
} // namespace operators } // namespace operators

View File

@ -41,6 +41,7 @@
#include "src/actions/block.h" #include "src/actions/block.h"
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/rule_with_operator.h" #include "src/rule_with_operator.h"
#include "modsecurity/string_view.hpp"
namespace modsecurity { namespace modsecurity {
@ -68,8 +69,9 @@ RuleWithOperator::~RuleWithOperator() {
} }
void RuleWithOperator::updateMatchedVars(Transaction *trans, const std::string &key, void RuleWithOperator::updateMatchedVars(Transaction *trans,
const std::string &value) { const std::string &key,
const bpstd::string_view &value) {
ms_dbg_a(trans, 9, "Matched vars updated."); ms_dbg_a(trans, 9, "Matched vars updated.");
trans->m_variableMatchedVar.set(value, trans->m_variableOffset); trans->m_variableMatchedVar.set(value, trans->m_variableOffset);
trans->m_variableMatchedVarName.set(key, trans->m_variableOffset); trans->m_variableMatchedVarName.set(key, trans->m_variableOffset);
@ -88,9 +90,9 @@ void RuleWithOperator::cleanMatchedVars(Transaction *trans) {
} }
bool RuleWithOperator::executeOperatorAt(Transaction *trans,
bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string &key, const std::string &key,
std::string value) { const bpstd::string_view &value) {
#if MSC_EXEC_CLOCK_ENABLED #if MSC_EXEC_CLOCK_ENABLED
clock_t begin = clock(); clock_t begin = clock();
clock_t end; clock_t end;
@ -98,16 +100,13 @@ bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string &
#endif #endif
bool ret; bool ret;
ms_dbg_a(trans, 9, "Target value: \"" + utils::string::limitTo(80, ms_dbg_a(trans, 9, "Target value: \"" \
utils::string::toHexIfNeeded(value)) \ + utils::string::limitTo(80,
utils::string::toHexIfNeeded(value.to_string())) \
+ "\" (Variable: " + key + ")"); + "\" (Variable: " + key + ")");
ret = m_operator->evaluateInternal(trans, this, value, trans->messageGetLast()); ret = m_operator->evaluateInternal(trans, this, value, trans->messageGetLast());
if (ret == false) {
return false;
}
#if MSC_EXEC_CLOCK_ENABLED #if MSC_EXEC_CLOCK_ENABLED
end = clock(); end = clock();
elapsed_s = static_cast<double>(end - begin) / CLOCKS_PER_SEC; elapsed_s = static_cast<double>(end - begin) / CLOCKS_PER_SEC;
@ -302,10 +301,9 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
while (iter != transformationsResults.end()) { while (iter != transformationsResults.end()) {
bool ret; bool ret;
auto &valueTemp = *iter; auto &valueTemp = *iter;
// FIXME: this copy is not necessary. bpstd::string_view view = *valueTemp.getAfter();
std::string *valueAfterTrans = new std::string(valueTemp.getAfter()->c_str(), valueTemp.getAfter()->size());
ret = executeOperatorAt(trans, key, *valueAfterTrans); ret = executeOperatorAt(trans, key, view);
if (ret == true) { if (ret == true) {
trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans, trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans,
@ -330,12 +328,12 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
iter2++; iter2++;
} }
updateMatchedVars(trans, key, *valueAfterTrans); updateMatchedVars(trans, key, view);
executeActionsIndependentOfChainedRuleResult(trans); executeActionsIndependentOfChainedRuleResult(trans);
globalRet = true; globalRet = true;
} }
delete valueAfterTrans;
iter++; iter++;
} }
delete v; delete v;

View File

@ -32,6 +32,7 @@
#include "src/rule_with_actions.h" #include "src/rule_with_actions.h"
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/operators/operator.h" #include "src/operators/operator.h"
#include "modsecurity/string_view.hpp"
#ifdef __cplusplus #ifdef __cplusplus
@ -61,11 +62,14 @@ class RuleWithOperator : public RuleWithActions {
inline void getFinalVars(variables::Variables *vars, inline void getFinalVars(variables::Variables *vars,
variables::Variables *eclusion, Transaction *trans); variables::Variables *eclusion, Transaction *trans);
bool executeOperatorAt(Transaction *trasn, const std::string &key, bool executeOperatorAt(Transaction *transaction,
std::string value); const std::string &key,
const bpstd::string_view &value);
static void updateMatchedVars(Transaction *transaction,
const std::string &key,
const bpstd::string_view &value);
static void updateMatchedVars(Transaction *trasn, const std::string &key,
const std::string &value);
static void cleanMatchedVars(Transaction *trasn); static void cleanMatchedVars(Transaction *trasn);

View File

@ -19,6 +19,12 @@
*:others/mbedtls/sha1.c *:others/mbedtls/sha1.c
//
// 3rd party string view
//
*:headers/modsecurity/string_view.hpp
// //
// Code imported from ModSecurity v2... // Code imported from ModSecurity v2...
// //
@ -30,11 +36,10 @@ invalidScanfArgType_int:src/rules_set_properties.cc:102
redundantAssignment:src/operators/pm.cc:94 redundantAssignment:src/operators/pm.cc:94
// //
// ModSecurity v3 code... // ModSecurity v3 code...
// //
unmatchedSuppression:src/utils/geo_lookup.cc:82 functionStatic:src/operators/geo_lookup.h:39
useInitializationList:src/utils/shared_files.h:87 useInitializationList:src/utils/shared_files.h:87
unmatchedSuppression:src/utils/msc_tree.cc unmatchedSuppression:src/utils/msc_tree.cc
functionStatic:headers/modsecurity/transaction.h:455 functionStatic:headers/modsecurity/transaction.h:455
@ -54,8 +59,8 @@ syntaxError:src/transaction.cc:62
noConstructor:src/variables/variable.h:152 noConstructor:src/variables/variable.h:152
duplicateBranch:src/request_body_processor/multipart.cc:93 duplicateBranch:src/request_body_processor/multipart.cc:93
danglingTempReference:src/modsecurity.cc:206 danglingTempReference:src/modsecurity.cc:206
knownConditionTrueFalse:src/operators/validate_url_encoding.cc:77 knownConditionTrueFalse:src/operators/validate_url_encoding.cc:79
knownConditionTrueFalse:src/operators/verify_svnr.cc:88 knownConditionTrueFalse:src/operators/verify_svnr.cc:90
noConstructor:src/actions/rule_id.h:33 noConstructor:src/actions/rule_id.h:33
functionStatic:src/actions/rule_id.h:35 functionStatic:src/actions/rule_id.h:35