mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Extends the direct access model to other collections
This commit is contained in:
committed by
Felipe Zimmerle
parent
ca24b6bb06
commit
f2d149fc5f
100
headers/modsecurity/anchored_set_variable.h
Normal file
100
headers/modsecurity/anchored_set_variable.h
Normal 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_
|
||||
|
68
headers/modsecurity/anchored_variable.h
Normal file
68
headers/modsecurity/anchored_variable.h
Normal 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_
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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_
|
||||
|
||||
|
||||
|
@@ -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("")),
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
};
|
||||
|
Reference in New Issue
Block a user