mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
Fix `capture' memory management
The capture action was implemented before the transaction concept. While partially ported to use the transaction, some of the elements were not freed correctly. Now it is fully ported to use the class Transaction.
This commit is contained in:
parent
e346454374
commit
ed8b0c85d7
@ -318,6 +318,13 @@ class Transaction {
|
|||||||
*/
|
*/
|
||||||
transaction::Collections m_collections;
|
transaction::Collections m_collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the whatever matched in the operation utilization.
|
||||||
|
* That variable will be further used by the capture action.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
std::list<std::string> m_matched;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string *m_ARGScombinedSizeStr;
|
std::string *m_ARGScombinedSizeStr;
|
||||||
std::string *m_namesArgs;
|
std::string *m_namesArgs;
|
||||||
|
@ -32,38 +32,15 @@ namespace modsecurity {
|
|||||||
namespace actions {
|
namespace actions {
|
||||||
|
|
||||||
bool Capture::evaluate(Rule *rule, Transaction *transaction) {
|
bool Capture::evaluate(Rule *rule, Transaction *transaction) {
|
||||||
operators::Operator *op = rule->op;
|
if (transaction->m_matched.empty()) {
|
||||||
std::list<std::string> *match;
|
|
||||||
|
|
||||||
operators::Pm *pm = dynamic_cast<operators::Pm *>(op);
|
|
||||||
if (pm != NULL) {
|
|
||||||
match = &pm->matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
operators::Rx *rx = dynamic_cast<operators::Rx *>(op);
|
|
||||||
if (rx != NULL) {
|
|
||||||
match = &rx->matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
operators::Contains *contains = dynamic_cast<operators::Contains *>(op);
|
|
||||||
if (contains != NULL) {
|
|
||||||
match = &contains->matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
operators::DetectSQLi *dsqli = dynamic_cast<operators::DetectSQLi *>(op);
|
|
||||||
if (dsqli != NULL) {
|
|
||||||
match = &dsqli->matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match->empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (match->empty() == false) {
|
while (transaction->m_matched.empty() == false) {
|
||||||
transaction->m_collections.storeOrUpdateFirst("TX",
|
transaction->m_collections.storeOrUpdateFirst("TX",
|
||||||
std::to_string(i), match->back());
|
std::to_string(i), transaction->m_matched.back());
|
||||||
match->pop_back();
|
transaction->m_matched.pop_back();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -27,7 +27,7 @@ bool Contains::evaluate(Transaction *transaction, const std::string &input) {
|
|||||||
bool contains = input.find(p) != std::string::npos;
|
bool contains = input.find(p) != std::string::npos;
|
||||||
|
|
||||||
if (contains) {
|
if (contains) {
|
||||||
matched.push_back(p);
|
transaction->m_matched.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negation) {
|
if (negation) {
|
||||||
|
@ -31,9 +31,8 @@ class Contains : public Operator {
|
|||||||
/** @ingroup ModSecurity_Operator */
|
/** @ingroup ModSecurity_Operator */
|
||||||
Contains(std::string op, std::string param, bool negation)
|
Contains(std::string op, std::string param, bool negation)
|
||||||
: Operator(op, param, negation) { }
|
: Operator(op, param, negation) { }
|
||||||
bool evaluate(Transaction *transaction, const std::string &exp) override;
|
|
||||||
|
|
||||||
std::list<std::string> matched;
|
bool evaluate(Transaction *transaction, const std::string &exp) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace operators
|
} // namespace operators
|
||||||
|
@ -32,8 +32,8 @@ bool DetectSQLi::evaluate(Transaction *transaction, const std::string &input) {
|
|||||||
issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);
|
issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);
|
||||||
|
|
||||||
if (issqli) {
|
if (issqli) {
|
||||||
matched.push_back(fingerprint);
|
|
||||||
if (transaction) {
|
if (transaction) {
|
||||||
|
transaction->m_matched.push_back(fingerprint);
|
||||||
#ifndef NO_LOGS
|
#ifndef NO_LOGS
|
||||||
transaction->debug(4, "detected SQLi using libinjection with " \
|
transaction->debug(4, "detected SQLi using libinjection with " \
|
||||||
"fingerprint '" + std::string(fingerprint) + "' at: '" +
|
"fingerprint '" + std::string(fingerprint) + "' at: '" +
|
||||||
|
@ -31,8 +31,6 @@ class DetectSQLi : public Operator {
|
|||||||
: Operator(op, param, negation) { }
|
: Operator(op, param, negation) { }
|
||||||
|
|
||||||
bool evaluate(Transaction *transaction, const std::string &input);
|
bool evaluate(Transaction *transaction, const std::string &input);
|
||||||
|
|
||||||
std::list<std::string> matched;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace operators
|
} // namespace operators
|
||||||
|
@ -78,7 +78,7 @@ bool Pm::evaluate(Transaction *transaction, const std::string &input) {
|
|||||||
|
|
||||||
rc = acmp_process_quick(&pt, &match, input.c_str(), input.length());
|
rc = acmp_process_quick(&pt, &match, input.c_str(), input.length());
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
this->matched.push_back(std::string(match));
|
transaction->m_matched.push_back(std::string(match));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc == 1;
|
return rc == 1;
|
||||||
|
@ -42,7 +42,6 @@ class Pm : public Operator {
|
|||||||
bool init(const std::string &file, const char **error) override;
|
bool init(const std::string &file, const char **error) override;
|
||||||
void postOrderTraversal(acmp_btree_node_t *node);
|
void postOrderTraversal(acmp_btree_node_t *node);
|
||||||
|
|
||||||
std::list<std::string> matched;
|
|
||||||
protected:
|
protected:
|
||||||
ACMP *m_p;
|
ACMP *m_p;
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@ bool Rx::evaluate(Transaction *transaction, const std::string& input) {
|
|||||||
SMatch match;
|
SMatch match;
|
||||||
|
|
||||||
if (regex_search(input, &match, *m_re) && match.size() >= 1) {
|
if (regex_search(input, &match, *m_re) && match.size() >= 1) {
|
||||||
this->matched.push_back(match.match);
|
transaction->m_matched.push_back(match.match);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ class Rx : public Operator {
|
|||||||
|
|
||||||
bool evaluate(Transaction *transaction, const std::string &input);
|
bool evaluate(Transaction *transaction, const std::string &input);
|
||||||
|
|
||||||
std::list<std::string> matched;
|
|
||||||
private:
|
private:
|
||||||
std::string m_param;
|
std::string m_param;
|
||||||
Regex *m_re;
|
Regex *m_re;
|
||||||
|
@ -272,6 +272,7 @@ bool Rule::evaluate(Transaction *trasn) {
|
|||||||
std::vector<Variable *> *variables = this->variables;
|
std::vector<Variable *> *variables = this->variables;
|
||||||
RuleMessage *ruleMessage = new modsecurity::RuleMessage(this, m_log_message);
|
RuleMessage *ruleMessage = new modsecurity::RuleMessage(this, m_log_message);
|
||||||
|
|
||||||
|
trasn->m_matched.clear();
|
||||||
|
|
||||||
if (m_secmarker == true) {
|
if (m_secmarker == true) {
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user