Extends the direct access model to other collections

This commit is contained in:
Felipe Zimmerle
2017-01-26 23:13:38 -03:00
committed by Felipe Zimmerle
parent ca24b6bb06
commit f2d149fc5f
157 changed files with 7711 additions and 4959 deletions

View File

@@ -0,0 +1,100 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#ifdef __cplusplus
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <vector>
#include <algorithm>
#include <iostream>
#endif
#include "modsecurity/collection/variable.h"
#ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_
#ifdef __cplusplus
namespace modsecurity {
class Transaction;
namespace Utils {
class Regex;
}
struct MyEqual {
bool operator()(const std::string& Left, const std::string& Right) const {
return Left.size() == Right.size()
&& std::equal(Left.begin(), Left.end(), Right.begin(),
[](char a, char b) {
return tolower(a) == tolower(b);
});
}
};
struct MyHash{
size_t operator()(const std::string& Keyval) const {
// You might need a better hash function than this
size_t h = 0;
std::for_each(Keyval.begin(), Keyval.end(), [&](char c) {
h += tolower(c);
});
return h;
}
};
class AnchoredSetVariable : public std::unordered_multimap<std::string, collection::Variable *,
MyHash, MyEqual> {
public:
AnchoredSetVariable(Transaction *t, std::string name);
~AnchoredSetVariable();
void unset();
void set(const std::string &key, const std::string &value,
size_t offset);
void resolve(std::vector<const collection::Variable *> *l);
void resolve(const std::string &key,
std::vector<const collection::Variable *> *l);
void resolveRegularExpression(Utils::Regex *r,
std::vector<const collection::Variable *> *l);
std::unique_ptr<std::string> resolveFirst(const std::string &key);
Transaction *m_transaction;
std::string m_name;
};
} // namespace modsecurity
#endif
#endif // HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_

View File

@@ -0,0 +1,68 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#ifdef __cplusplus
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#endif
#include "modsecurity/collection/variable.h"
#ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_
#ifdef __cplusplus
namespace modsecurity {
class Transaction;
class AnchoredVariable {
public:
AnchoredVariable(Transaction* t, std::__cxx11::string name);
~AnchoredVariable();
void unset();
void set(const std::string &a, size_t offset);
void append(const std::string &a, size_t offset,
bool spaceSeparator = false);
void evaluate(std::vector<const collection::Variable *> *l);
std::string * evaluate();
std::unique_ptr<std::string> resolveFirst();
Transaction *m_transaction;
collection::Variable *m_var;
int m_offset;
std::string m_name;
std::string m_value;
};
} // namespace modsecurity
#endif
#endif // HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_

View File

@@ -50,7 +50,7 @@ class Collection {
virtual void del(const std::string& key) = 0;
virtual std::string* resolveFirst(const std::string& var) = 0;
virtual std::unique_ptr<std::string> resolveFirst(const std::string& var) = 0;
virtual void resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l) = 0;
@@ -83,7 +83,7 @@ class Collection {
del(nkey);
}
virtual std::string* resolveFirst(const std::string& var,
virtual std::unique_ptr<std::string> resolveFirst(const std::string& var,
std::string compartment) {
std::string nkey = compartment + "::" + var;
return resolveFirst(nkey);

View File

@@ -56,8 +56,8 @@ class Collections :
bool storeOrUpdateFirst(const std::string &key, const std::string &value);
bool updateFirst(const std::string &key, const std::string &value);
void del(const std::string& key);
std::string* resolveFirst(const std::string& var);
std::string* resolveFirst(const std::string& collectionName,
std::unique_ptr<std::string> resolveFirst(const std::string& var);
std::unique_ptr<std::string> resolveFirst(const std::string& collectionName,
const std::string& var);
void resolveSingleMatch(const std::string& var,

View File

@@ -40,22 +40,28 @@ class Variable {
m_key(key),
m_value(),
m_dynamic_value(false),
m_dynamic_key(false),
m_dynamic(true) { }
Variable(const std::string *key, const std::string *value) :
m_key(key),
m_value(value),
m_dynamic_value(false),
m_dynamic_key(false),
m_dynamic(true) { }
~Variable() {
if (m_dynamic_value) {
delete m_value;
}
if (m_dynamic_key) {
delete m_key;
}
}
const std::string *m_key;
const std::string *m_value;
bool m_dynamic_value;
bool m_dynamic_key;
bool m_dynamic;
std::list<std::unique_ptr<VariableOrigin>> m_orign;
};

View File

@@ -48,12 +48,12 @@ class Rule {
std::vector<actions::Action *> *_actions,
std::string fileName,
int lineNumber);
explicit Rule(std::string marker);
Rule(std::__cxx11::string marker);
~Rule();
bool evaluate(Transaction *transaction);
bool evaluateActions(Transaction *transaction);
std::vector<const collection::Variable *> getFinalVars(Transaction *trasn);
std::vector<std::unique_ptr<collection::Variable>> getFinalVars(Transaction *trasn);
void executeActionsAfterFullMatch(Transaction *trasn,
bool containsDisruptive, RuleMessage *ruleMessage);
std::list<
@@ -73,22 +73,10 @@ class Rule {
void cleanMatchedVars(Transaction *trasn);
void updateRulesVariable(Transaction *trasn);
operators::Operator *op;
std::vector<actions::Action *> m_actionsConf;
std::vector<actions::Action *> m_actionsRuntimePre;
std::vector<actions::Action *> m_actionsRuntimePos;
std::vector<std::string> getActionNames();
std::vector<actions::Action *> getActionsByName(const std::string& name);
bool containsTag(const std::string& name, Transaction *t);
std::vector<Variables::Variable *> *variables;
int phase;
long rule_id;
Rule *chainedRule;
bool chained;
int refCountDecreaseAndCheck() {
m_referenceCount--;
@@ -99,22 +87,30 @@ class Rule {
return 0;
}
void refCountIncrease() {
m_referenceCount++;
}
std::string m_rev;
std::string m_ver;
std::string m_marker;
bool m_secmarker;
int m_accuracy;
std::vector<actions::Action *> m_actionsConf;
std::vector<actions::Action *> m_actionsRuntimePos;
std::vector<actions::Action *> m_actionsRuntimePre;
bool m_chained;
Rule *m_chainedRule;
std::string m_fileName;
int m_lineNumber;
std::string m_log_data;
int m_accuracy;
std::string m_logData;
std::string m_marker;
int m_maturity;
operators::Operator *m_op;
int m_phase;
std::string m_rev;
long m_ruleId;
bool m_secMarker;
std::vector<Variables::Variable *> *m_variables;
std::string m_ver;
private:
bool m_unconditional;
int m_referenceCount;
@@ -126,5 +122,3 @@ class Rule {
#endif // HEADERS_MODSECURITY_RULE_H_

View File

@@ -37,7 +37,7 @@ class RuleMessage {
explicit RuleMessage(Rule *rule) :
m_ruleFile(rule->m_fileName),
m_ruleLine(rule->m_lineNumber),
m_ruleId(rule->rule_id),
m_ruleId(rule->m_ruleId),
m_rev(rule->m_rev),
m_accuracy(rule->m_accuracy),
m_message(std::string("")),

View File

@@ -390,12 +390,12 @@ class RulesProperties {
Rule *rule = rules_from->at(j);
for (int z = 0; z < rules_to->size(); z++) {
Rule *rule_ckc = rules_to->at(z);
if (rule_ckc->rule_id == rule->rule_id &&
rule_ckc->m_secmarker == false &&
rule->m_secmarker == false) {
if (rule_ckc->m_ruleId == rule->m_ruleId &&
rule_ckc->m_secMarker == false &&
rule->m_secMarker == false) {
if (err != NULL) {
*err << "Rule id: " \
<< std::to_string(rule->rule_id) \
<< std::to_string(rule->m_ruleId) \
<< " is duplicated" << std::endl;
}
return -1;

View File

@@ -40,12 +40,15 @@ typedef struct Transaction_t Transaction;
typedef struct Rules_t Rules;
#endif
#include "modsecurity/anchored_set_variable.h"
#include "modsecurity/anchored_variable.h"
#include "modsecurity/intervention.h"
#include "modsecurity/collection/collections.h"
#include "modsecurity/collection/variable.h"
#include "modsecurity/collection/collection.h"
#include "modsecurity/variable_origin.h"
#define LOGFY_ADD(a, b) \
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
if (b == NULL) { \
@@ -88,142 +91,6 @@ class Operator;
}
struct MyEqual {
bool operator()(const std::string& Left, const std::string& Right) const {
return Left.size() == Right.size()
&& std::equal(Left.begin(), Left.end(), Right.begin(),
[](char a, char b) {
return tolower(a) == tolower(b);
});
}
};
struct MyHash{
size_t operator()(const std::string& Keyval) const {
// You might need a better hash function than this
size_t h = 0;
std::for_each(Keyval.begin(), Keyval.end(), [&](char c) {
h += tolower(c);
});
return h;
}
};
class AnchoredSetVariable : public std::unordered_multimap<std::string,
collection::Variable *, MyHash, MyEqual> {
public:
AnchoredSetVariable(Transaction *t, std::string name)
: m_name(""),
m_transaction(t) {
m_name.append(name);
}
~AnchoredSetVariable() {
for (const auto& x : *this) {
collection::Variable *var = x.second;
delete var->m_key;
delete var;
}
}
void set(const std::string &key, const std::string &value,
size_t offset) {
std::string *v = new std::string(value);
std::string *k = new std::string(m_name + ":" + key);
collection::Variable *var = new collection::Variable(k, v);
var->m_dynamic_value = true;
var->m_dynamic = false;
emplace(key, var);
}
void resolve(std::vector<const collection::Variable *> *l) {
for (const auto& x : *this) {
l->insert(l->begin(), x.second);
}
}
void resolve(const std::string &key,
std::vector<const collection::Variable *> *l) {
auto range = this->equal_range(key);
for (auto it = range.first; it != range.second; ++it) {
l->push_back(it->second);
}
}
void resolveRegularExpression(const std::string &var,
std::vector<const collection::Variable *> *l);
Transaction *m_transaction;
std::string m_name;
};
class AnchoredVariable {
public:
AnchoredVariable(Transaction *t, std::string name)
: m_name(""),
m_transaction(t),
m_value("") {
m_name.append(name);
m_var = new collection::Variable(&m_name);
m_var->m_dynamic = false;
m_var->m_value = &m_value;
}
~AnchoredVariable() {
delete (m_var);
m_var = NULL;
}
void set(const std::string &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->m_orign.push_back(std::move(origin));
}
void append(const std::string &a, size_t offset,
bool spaceSeparator = false) {
std::unique_ptr<VariableOrigin> origin(
new VariableOrigin());
if (spaceSeparator && !m_value.empty()) {
m_value.append(" " + a);
} else {
m_value.append(a);
}
m_offset = offset;
origin->m_offset = offset;
origin->m_length = a.size();
m_var->m_orign.push_back(std::move(origin));
}
void evaluate(std::vector<const collection::Variable *> *l) {
if (m_name.empty() || m_var->m_key == NULL
|| m_var->m_value == NULL || m_var->m_key->empty()) {
return;
}
l->push_back(m_var);
}
std::string *evaluate() {
if (m_value.empty() == true) {
return NULL;
}
return &m_value;
}
int m_offset;
std::string m_value;
Transaction *m_transaction;
std::string m_name;
collection::Variable *m_var;
};
class TransactionAnchoredVariables {
public:
explicit TransactionAnchoredVariables(Transaction *t)
@@ -236,7 +103,6 @@ class TransactionAnchoredVariables {
m_variableARGScombinedSize(t, "ARGS_COMBINED_SIZE"),
m_variableAuthType(t, "AUTH_TYPE"),
m_variableFilesCombinedSize(t, "FILES_COMBINED_SIZE"),
m_variableFilesTmpNames(t, "FILES_TMPNAMES"),
m_variableFullRequest(t, "FULL_REQUEST"),
m_variableFullRequestLength(t, "FULL_REQUEST_LENGTH"),
m_variableInboundDataError(t, "INBOUND_DATA_ERROR"),
@@ -285,8 +151,25 @@ class TransactionAnchoredVariables {
m_variableUniqueID(t, "UNIQUE_ID"),
m_variableUrlEncodedError(t, "URLENCODED_ERROR"),
m_variableUserID(t, "USERID"),
m_variableOffset(0),
m_variableArgs(t, "ARGS")
m_variableArgs(t, "ARGS"),
m_variableArgsGet(t, "ARGS_GET"),
m_variableArgsPost(t, "ARGS_POST"),
m_variableFilesSizes(t, "FILES_SIZES"),
m_variableFilesNames(t, "FILES_NAMES"),
m_variableFilesTmpContent(t, "FILES_TMP_CONTENT"),
m_variableMultiPartFileName(t, "MULTIPART_FILENAME"),
m_variableMultiPartName(t, "MULTIPART_NAME"),
m_variableMatchedVarsNames(t, "MATCHED_VARS_NAMES"),
m_variableMatchedVars(t, "MATCHED_VARS"),
m_variableFiles(t, "FILES"),
m_variableRequestCookies(t, "REQUEST_COOKIES"),
m_variableRequestHeaders(t, "REQUEST_HEADERS"),
m_variableResponseHeaders(t, "RESPONSE_HEADERS"),
m_variableGeo(t, "GEO"),
m_variableRequestCookiesNames(t, "REQUEST_COOKIES_NAMES"),
m_variableRule(t, "RULE"),
m_variableFilesTmpNames(t, "FILES_TMPNAMES"),
m_variableOffset(0)
{ }
AnchoredVariable m_variableArgsNames;
@@ -298,7 +181,6 @@ class TransactionAnchoredVariables {
AnchoredVariable m_variableARGScombinedSize;
AnchoredVariable m_variableAuthType;
AnchoredVariable m_variableFilesCombinedSize;
AnchoredVariable m_variableFilesTmpNames;
AnchoredVariable m_variableFullRequest;
AnchoredVariable m_variableFullRequestLength;
AnchoredVariable m_variableInboundDataError;
@@ -346,6 +228,23 @@ class TransactionAnchoredVariables {
AnchoredVariable m_variableUserID;
AnchoredSetVariable m_variableArgs;
AnchoredSetVariable m_variableArgsGet;
AnchoredSetVariable m_variableArgsPost;
AnchoredSetVariable m_variableFilesSizes;
AnchoredSetVariable m_variableFilesNames;
AnchoredSetVariable m_variableFilesTmpContent;
AnchoredSetVariable m_variableMultiPartFileName;
AnchoredSetVariable m_variableMultiPartName;
AnchoredSetVariable m_variableMatchedVarsNames;
AnchoredSetVariable m_variableMatchedVars;
AnchoredSetVariable m_variableFiles;
AnchoredSetVariable m_variableRequestCookies;
AnchoredSetVariable m_variableRequestHeaders;
AnchoredSetVariable m_variableResponseHeaders;
AnchoredSetVariable m_variableGeo;
AnchoredSetVariable m_variableRequestCookiesNames;
AnchoredSetVariable m_variableRule;
AnchoredSetVariable m_variableFilesTmpNames;
int m_variableOffset;
};