Adds support to multiple ranges in ctl:ruleRemoveById

Issue #1956
This commit is contained in:
Felipe Zimmerle
2018-11-26 20:46:05 -03:00
parent e712d30c56
commit ce3abf2626
7 changed files with 265 additions and 11 deletions

View File

@@ -19,6 +19,7 @@
#include <string>
#include "modsecurity/transaction.h"
#include "src/utils/string.h"
namespace modsecurity {
namespace actions {
@@ -27,20 +28,69 @@ namespace ctl {
bool RuleRemoveById::init(std::string *error) {
std::string what(m_parser_payload, 15, m_parser_payload.size() - 15);
bool added = false;
std::vector<std::string> toRemove = utils::string::ssplit(what, ' ');
for (std::string &a : toRemove) {
std::string b = modsecurity::utils::string::parserSanitizer(a);
if (b.size() == 0) {
continue;
}
try {
m_id = std::stoi(what);
} catch(...) {
error->assign("Not able to convert '" + what +
"' into a number");
return false;
size_t dash = b.find('-');
if (dash != std::string::npos) {
std::string n1s = std::string(b, 0, dash);
std::string n2s = std::string(b, dash + 1, b.size() - (dash + 1));
int n1n = 0;
int n2n = 0;
try {
n1n = std::stoi(n1s);
added = true;
} catch (...) {
error->assign("Not a number: " + n1s);
return false;
}
try {
n2n = std::stoi(n2s);
added = true;
} catch (...) {
error->assign("Not a number: " + n2s);
return false;
}
if (n1s > n2s) {
error->assign("Invalid range: " + b);
return false;
}
m_ranges.push_back(std::make_pair(n1n, n2n));
added = true;
} else {
try {
int num = std::stoi(b);
m_ids.push_back(num);
added = true;
} catch (...) {
error->assign("Not a number or range: " + b);
return false;
}
}
}
return true;
if (added) {
return true;
}
error->assign("Not a number or range: " + what);
return false;
}
bool RuleRemoveById::evaluate(Rule *rule, Transaction *transaction) {
transaction->m_ruleRemoveById.push_back(m_id);
for (auto &i : m_ids) {
transaction->m_ruleRemoveById.push_back(i);
}
for (auto &i : m_ranges) {
transaction->m_ruleRemoveByIdRange.push_back(i);
}
return true;
}

View File

@@ -30,13 +30,13 @@ namespace ctl {
class RuleRemoveById : public Action {
public:
explicit RuleRemoveById(std::string action)
: Action(action, RunTimeOnlyIfMatchKind),
m_id(0) { }
: Action(action, RunTimeOnlyIfMatchKind) { }
bool init(std::string *error) override;
bool evaluate(Rule *rule, Transaction *transaction) override;
int m_id;
std::list<std::pair<int, int> > m_ranges;
std::list<int> m_ids;
};

View File

@@ -656,6 +656,14 @@ bool Rule::evaluate(Transaction *trans,
" was skipped due to a ruleRemoveById action...");
return true;
}
for (auto &i : trans->m_ruleRemoveByIdRange) {
if (!(i.first <= m_ruleId && i.second >= m_ruleId)) {
continue;
}
ms_dbg_a(trans, 9, "Rule id: " + std::to_string(m_ruleId) +
" was skipped due to a ruleRemoveById action...");
return true;
}
if (m_op->m_string) {
eparam = m_op->m_string->evaluate(trans);