diff --git a/headers/modsecurity/variable_value.h b/headers/modsecurity/variable_value.h index 6896a859..7c36170b 100644 --- a/headers/modsecurity/variable_value.h +++ b/headers/modsecurity/variable_value.h @@ -37,59 +37,31 @@ namespace modsecurity { class Collection; class VariableValue { public: - explicit VariableValue(const std::string *key) - : m_key(""), - m_value("") { - m_key.assign(*key); - m_keyWithCollection = std::make_shared(*key); - } + using Origins = std::list>; - VariableValue(const std::string *key, const std::string *value) - : m_key(""), - m_value("") { - m_key.assign(*key); - m_value.assign(*value); - m_keyWithCollection = std::make_shared(*key); - } + VariableValue(const std::string *key, + const std::string *value = nullptr) + : m_key(*key), + m_keyWithCollection(*key), + m_collection(""), + m_value(value != nullptr?*value:"") + { } - VariableValue() - : m_key(""), - m_value("") { - m_keyWithCollection = std::make_shared(m_key); - } - - VariableValue(const std::string *a, const std::string *b, - const std::string *c) - : m_key(*a + ":" + *b), - m_value(*c) { - m_keyWithCollection = std::make_shared(*a + ":" + *b); - } - - explicit VariableValue(std::shared_ptr fullName) - : m_key(""), - m_value("") { - m_keyWithCollection = fullName; - m_key.assign(*fullName.get()); - } - - VariableValue(std::shared_ptr fullName, + VariableValue(const std::string *collection, + const std::string *key, const std::string *value) - : m_key(""), - m_value("") { - m_value.assign(*value); - m_keyWithCollection = fullName; - m_key.assign(*fullName.get()); - } - + : m_key(*key), + m_keyWithCollection(*collection + ":" + *key), + m_collection(*collection), + m_value(*value) + { } explicit VariableValue(const VariableValue *o) : - m_key(""), - m_value("") { - m_key.assign(o->m_key); - m_value.assign(o->m_value); - m_col.assign(o->m_col); - m_keyWithCollection = o->m_keyWithCollection; - + m_key(o->m_key), + m_value(o->m_value), + m_collection(o->m_collection), + m_keyWithCollection(o->m_keyWithCollection) + { for (auto &i : o->m_orign) { std::unique_ptr origin(new VariableOrigin()); origin->m_offset = i->m_offset; @@ -98,11 +70,47 @@ class VariableValue { } } + + const std::string& getKey() const { + return m_key; + } + + + const std::string& getKeyWithCollection() const { + return m_keyWithCollection; + } + + + const std::string& getCollection() const { + return m_collection; + } + + + const std::string& getValue() const { + return m_value; + } + + + void setValue(const std::string &value) { + m_value = value; + } + + + void addOrigin(std::unique_ptr origin) { + m_orign.push_back(std::move(origin)); + } + + + const Origins& getOrigin() const { + return m_orign; + } + + private: + Origins m_orign; + std::string m_collection; std::string m_key; + std::string m_keyWithCollection; std::string m_value; - std::string m_col; - std::shared_ptr m_keyWithCollection; - std::list> m_orign; }; } // namespace modsecurity diff --git a/src/Makefile.am b/src/Makefile.am index 696c8552..54c54fb3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,6 +88,7 @@ VARIABLES = \ variables/highest_severity.cc \ variables/modsec_build.cc \ variables/remote_user.cc \ + variables/rule.cc \ variables/time.cc \ variables/time_day.cc \ variables/time_epoch.cc \ diff --git a/src/actions/set_var.cc b/src/actions/set_var.cc index 6f6dbe77..427e11f2 100644 --- a/src/actions/set_var.cc +++ b/src/actions/set_var.cc @@ -117,7 +117,7 @@ bool SetVar::evaluate(Rule *rule, Transaction *t) { if (l.size() == 0) { value = 0; } else { - value = stoi(l[0]->m_value); + value = stoi(l[0]->getValue()); for (auto &i : l) { delete i; } diff --git a/src/anchored_set_variable.cc b/src/anchored_set_variable.cc index 2ff10e8a..622d977c 100644 --- a/src/anchored_set_variable.cc +++ b/src/anchored_set_variable.cc @@ -53,14 +53,13 @@ void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset, size_t len) { std::unique_ptr origin(new VariableOrigin()); std::string *v = new std::string(value); - VariableValue *var = new VariableValue(std::make_shared( - m_name + ":" + key), v); + VariableValue *var = new VariableValue(&m_name, &key, v); delete v; origin->m_offset = offset; origin->m_length = len; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); emplace(key, var); } @@ -69,14 +68,13 @@ void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset) { std::unique_ptr origin(new VariableOrigin()); std::string *v = new std::string(value); - VariableValue *var = new VariableValue(std::make_shared( - m_name + ":" + key), v); + VariableValue *var = new VariableValue(&m_name, &key, v); delete v; origin->m_offset = offset; origin->m_length = value.size(); - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); emplace(key, var); } @@ -117,7 +115,7 @@ std::unique_ptr AnchoredSetVariable::resolveFirst( auto range = equal_range(key); for (auto it = range.first; it != range.second; ++it) { std::unique_ptr b(new std::string()); - b->assign(it->second->m_value); + b->assign(it->second->getValue()); return b; } return nullptr; diff --git a/src/anchored_variable.cc b/src/anchored_variable.cc index 2dba3af6..2bedc8fd 100644 --- a/src/anchored_variable.cc +++ b/src/anchored_variable.cc @@ -60,7 +60,7 @@ void AnchoredVariable::set(const std::string &a, size_t offset, m_value.assign(a.c_str(), a.size()); origin->m_offset = offset; origin->m_length = offsetLen; - m_var->m_orign.push_back(std::move(origin)); + m_var->addOrigin(std::move(origin)); } @@ -71,7 +71,7 @@ void AnchoredVariable::set(const std::string &a, size_t 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)); + m_var->addOrigin(std::move(origin)); } @@ -88,7 +88,7 @@ void AnchoredVariable::append(const std::string &a, size_t offset, m_offset = offset; origin->m_offset = offset; origin->m_length = a.size(); - m_var->m_orign.push_back(std::move(origin)); + m_var->addOrigin(std::move(origin)); } @@ -105,7 +105,7 @@ void AnchoredVariable::append(const std::string &a, size_t offset, m_offset = offset; origin->m_offset = offset; origin->m_length = size; - m_var->m_orign.push_back(std::move(origin)); + m_var->addOrigin(std::move(origin)); } @@ -114,7 +114,7 @@ void AnchoredVariable::evaluate(std::vector *l) { return; } - m_var->m_value.assign(m_value); + m_var->setValue(m_value); VariableValue *m_var2 = new VariableValue(m_var); l->push_back(m_var2); } diff --git a/src/engine/lua.cc b/src/engine/lua.cc index abc7e682..a7dbd819 100644 --- a/src/engine/lua.cc +++ b/src/engine/lua.cc @@ -294,11 +294,11 @@ int Lua::getvars(lua_State *L) { lua_newtable(L); lua_pushstring(L, "name"); - lua_pushlstring(L, i->m_key.c_str(), i->m_key.size()); + lua_pushlstring(L, i->getKeyWithCollection().c_str(), i->getKeyWithCollection().size()); lua_settable(L, -3); lua_pushstring(L, "value"); - lua_pushlstring(L, i->m_value.c_str(), i->m_value.size()); + lua_pushlstring(L, i->getValue().c_str(), i->getValue().size()); lua_settable(L, -3); lua_settable(L, -3); diff --git a/src/rule.cc b/src/rule.cc index bcca52fe..64168a5c 100644 --- a/src/rule.cc +++ b/src/rule.cc @@ -696,25 +696,25 @@ bool Rule::evaluate(Transaction *trans, } var->evaluate(trans, this, &e); for (const VariableValue *v : e) { - const std::string &value = v->m_value; - const std::string &key = v->m_key; + const std::string &value = v->getValue(); + const std::string &key = v->getKeyWithCollection(); - if (exclusion.contains(v->m_key) || + if (exclusion.contains(v->getKeyWithCollection()) || std::find_if(trans->m_ruleRemoveTargetById.begin(), trans->m_ruleRemoveTargetById.end(), [&, v, this](std::pair &m) -> bool { - return m.first == m_ruleId && m.second == v->m_key; + return m.first == m_ruleId && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetById.end() ) { delete v; v = NULL; continue; } - if (exclusion.contains(v->m_key) || + if (exclusion.contains(v->getKeyWithCollection()) || std::find_if(trans->m_ruleRemoveTargetByTag.begin(), trans->m_ruleRemoveTargetByTag.end(), [&, v, trans, this](std::pair &m) -> bool { - return containsTag(m.first, trans) && m.second == v->m_key; + return containsTag(m.first, trans) && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetByTag.end() ) { delete v; @@ -736,7 +736,7 @@ bool Rule::evaluate(Transaction *trans, if (ret == true) { ruleMessage->m_match = m_op->resolveMatchMessage(trans, key, value); - for (auto &i : v->m_orign) { + for (auto &i : v->getOrigin()) { ruleMessage->m_reference.append(i->toText()); } diff --git a/src/run_time_string.cc b/src/run_time_string.cc index dc816750..9d60cfc4 100644 --- a/src/run_time_string.cc +++ b/src/run_time_string.cc @@ -60,7 +60,7 @@ std::string RunTimeString::evaluate(Transaction *t, Rule *r) { std::vector l; z->m_var->evaluate(t, r, &l); if (l.size() > 0) { - s.append(l[0]->m_value); + s.append(l[0]->getValue()); } for (auto &i : l) { delete i; diff --git a/src/transaction.cc b/src/transaction.cc index 49daab12..e2d5190c 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -820,9 +820,7 @@ int Transaction::processRequestBody() { std::vector l; m_variableRequestHeaders.resolve(&l); for (auto &a : l) { - std::string z(a->m_key, 16, a->m_key.length() - 16); - z = z + ": " + a->m_value; - fullRequest = fullRequest + z + "\n"; + fullRequest = fullRequest + a->getKey() + ": " + a->getValue() + "\n"; delete a; } @@ -1443,8 +1441,8 @@ std::string Transaction::toOldAuditLogFormat(int parts, m_variableRequestHeaders.resolve(&l); for (auto &h : l) { size_t pos = strlen("REQUEST_HEADERS:"); - audit_log << h->m_key.c_str() + pos << ": "; - audit_log << h->m_value.c_str() << std::endl; + audit_log << h->getKeyWithCollection().c_str() + pos << ": "; + audit_log << h->getValue().c_str() << std::endl; delete h; } audit_log << std::endl; @@ -1480,9 +1478,8 @@ std::string Transaction::toOldAuditLogFormat(int parts, audit_log << this->m_httpCodeReturned << std::endl; m_variableResponseHeaders.resolve(&l); for (auto &h : l) { - size_t pos = strlen("RESPONSE_HEADERS:"); - audit_log << h->m_key.c_str() + pos << ": "; - audit_log << h->m_value.c_str() << std::endl; + audit_log << h->getKey().c_str() << ": "; + audit_log << h->getValue().c_str() << std::endl; delete h; } } @@ -1580,8 +1577,7 @@ std::string Transaction::toJSON(int parts) { m_variableRequestHeaders.resolve(&l); for (auto &h : l) { - size_t pos = strlen("REQUEST_HEADERS:"); - LOGFY_ADD(h->m_key.c_str() + pos, h->m_value.c_str()); + LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); delete h; } @@ -1611,8 +1607,7 @@ std::string Transaction::toJSON(int parts) { m_variableResponseHeaders.resolve(&l); for (auto &h : l) { - size_t pos = strlen("RESPONSE_HEADERS:"); - LOGFY_ADD(h->m_key.c_str() + pos, h->m_value.c_str()); + LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); delete h; } diff --git a/src/variables/highest_severity.cc b/src/variables/highest_severity.cc index eb28fd86..9ace72df 100644 --- a/src/variables/highest_severity.cc +++ b/src/variables/highest_severity.cc @@ -31,7 +31,7 @@ void HighestSeverity::evaluate(Transaction *transaction, std::vector *l) { transaction->m_variableHighestSeverityAction.assign( std::to_string(transaction->m_highestSeverityAction)); - l->push_back(new VariableValue(m_fullName, + l->push_back(new VariableValue(m_fullName.get(), &transaction->m_variableHighestSeverityAction)); } diff --git a/src/variables/highest_severity.h b/src/variables/highest_severity.h index 986fdca6..42c602d3 100644 --- a/src/variables/highest_severity.h +++ b/src/variables/highest_severity.h @@ -31,13 +31,12 @@ namespace variables { class HighestSeverity : public Variable { public: explicit HighestSeverity(std::string _name) - : Variable(_name), - m_retName("HIGHEST_SEVERITY") { } + : Variable(_name) + { } void evaluate(Transaction *transaction, Rule *rule, std::vector *l) override; - std::string m_retName; }; diff --git a/src/variables/remote_user.cc b/src/variables/remote_user.cc index ea8fae4e..d11ddb8f 100644 --- a/src/variables/remote_user.cc +++ b/src/variables/remote_user.cc @@ -52,7 +52,7 @@ void RemoteUser::evaluate(Transaction *transaction, goto clear; } - header = std::string(l2->at(0)->m_value); + header = std::string(l2->at(0)->getValue()); if (header.compare(0, 6, "Basic ") == 0) { base64 = std::string(header, 6, header.length()); @@ -66,14 +66,14 @@ void RemoteUser::evaluate(Transaction *transaction, } transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); - var = new VariableValue(&l2->at(0)->m_key, + var = new VariableValue(&l2->at(0)->getKeyWithCollection(), &transaction->m_variableRemoteUser); - for (auto &i : l2->at(0)->m_orign) { + for (auto &i : l2->at(0)->getOrigin()) { std::unique_ptr origin(new VariableOrigin()); origin->m_offset = i->m_offset; origin->m_length = i->m_length; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); } l->push_back(var); diff --git a/src/variables/rule.cc b/src/variables/rule.cc new file mode 100644 index 00000000..1f5713b2 --- /dev/null +++ b/src/variables/rule.cc @@ -0,0 +1,32 @@ +/* + * 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. + * + */ + +#include "src/variables/rule.h" + + +namespace modsecurity { +namespace variables { + + +const std::string Rule_DictElement::m_rule("RULE"); +const std::string Rule_DictElement::m_rule_id("id"); +const std::string Rule_DictElement::m_rule_rev("rev"); +const std::string Rule_DictElement::m_rule_severity("severity"); +const std::string Rule_DictElement::m_rule_logdata("logdata"); +const std::string Rule_DictElement::m_rule_msg("msg"); + + +} // namespace variables +} // namespace modsecurity diff --git a/src/variables/rule.h b/src/variables/rule.h index d51dc6b0..4f58113d 100644 --- a/src/variables/rule.h +++ b/src/variables/rule.h @@ -35,7 +35,7 @@ namespace variables { class Rule_DictElement : public VariableDictElement { \ public: explicit Rule_DictElement(std::string dictElement) - : VariableDictElement("RULE", dictElement) { } + : VariableDictElement(std::string("RULE"), dictElement) { } static void id(Transaction *t, Rule *rule, @@ -51,14 +51,13 @@ class Rule_DictElement : public VariableDictElement { \ } std::unique_ptr origin(new VariableOrigin()); std::string *a = new std::string(std::to_string(r->m_ruleId)); - VariableValue *var = new VariableValue( - std::make_shared("RULE:id"), + VariableValue *var = new VariableValue(&m_rule, &m_rule_id, a ); delete a; origin->m_offset = 0; origin->m_length = 0; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); l->push_back(var); } @@ -78,14 +77,13 @@ class Rule_DictElement : public VariableDictElement { \ std::unique_ptr origin(new VariableOrigin()); std::string *a = new std::string(r->m_rev); - VariableValue *var = new VariableValue( - std::make_shared("RULE:rev"), + VariableValue *var = new VariableValue(&m_rule, &m_rule_rev, a ); delete a; origin->m_offset = 0; origin->m_length = 0; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); l->push_back(var); } @@ -102,14 +100,13 @@ class Rule_DictElement : public VariableDictElement { \ if (r && r->m_severity) { std::unique_ptr origin(new VariableOrigin()); std::string *a = new std::string(std::to_string(r->m_severity->m_severity)); - VariableValue *var = new VariableValue( - std::make_shared("RULE:severity"), + VariableValue *var = new VariableValue(&m_rule, &m_rule_severity, a ); delete a; origin->m_offset = 0; origin->m_length = 0; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); l->push_back(var); } } @@ -127,14 +124,13 @@ class Rule_DictElement : public VariableDictElement { \ if (r && r->m_logData) { std::unique_ptr origin(new VariableOrigin()); std::string *a = new std::string(r->m_logData->data(t)); - VariableValue *var = new VariableValue( - std::make_shared("RULE:logdata"), + VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata, a ); delete a; origin->m_offset = 0; origin->m_length = 0; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); l->push_back(var); } } @@ -151,14 +147,13 @@ class Rule_DictElement : public VariableDictElement { \ if (r && r->m_msg) { std::unique_ptr origin(new VariableOrigin()); std::string *a = new std::string(r->m_msg->data(t)); - VariableValue *var = new VariableValue( - std::make_shared("RULE:msg"), + VariableValue *var = new VariableValue(&m_rule, &m_rule_msg, a ); delete a; origin->m_offset = 0; origin->m_length = 0; - var->m_orign.push_back(std::move(origin)); + var->addOrigin(std::move(origin)); l->push_back(var); } } @@ -187,6 +182,13 @@ class Rule_DictElement : public VariableDictElement { \ return; } } + + static const std::string m_rule; + static const std::string m_rule_id; + static const std::string m_rule_rev; + static const std::string m_rule_severity; + static const std::string m_rule_logdata; + static const std::string m_rule_msg; }; diff --git a/src/variables/variable.h b/src/variables/variable.h index d4b12c1f..e62ed6c1 100644 --- a/src/variables/variable.h +++ b/src/variables/variable.h @@ -658,7 +658,7 @@ class VariableModificatorCount : public Variable { reslIn.clear(); std::string *res = new std::string(std::to_string(count)); - val = new VariableValue(m_fullName, res); + val = new VariableValue(m_fullName.get(), res); delete res; l->push_back(val); diff --git a/src/variables/xml.cc b/src/variables/xml.cc index c83bc0ed..b508ad98 100644 --- a/src/variables/xml.cc +++ b/src/variables/xml.cc @@ -125,7 +125,7 @@ void XML::evaluate(Transaction *t, xmlNodeGetContent(nodes->nodeTab[i])); if (content != NULL) { std::string *a = new std::string(content); - VariableValue *var = new VariableValue(m_fullName, + VariableValue *var = new VariableValue(m_fullName.get(), a); if (!m_keyExclusion.toOmit(*m_fullName)) { l->push_back(var);