mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-16 07:56:12 +03:00
Makes RULE collection to be resolved inside a macro expansion
This commit is contained in:
parent
5514b66145
commit
5d64f73817
@ -90,9 +90,9 @@ bool SetVar::init(std::string *error) {
|
|||||||
bool SetVar::evaluate(Rule *rule, Transaction *transm_parser_payload) {
|
bool SetVar::evaluate(Rule *rule, Transaction *transm_parser_payload) {
|
||||||
std::string targetValue;
|
std::string targetValue;
|
||||||
std::string m_variableNameExpanded = MacroExpansion::expand(m_variableName,
|
std::string m_variableNameExpanded = MacroExpansion::expand(m_variableName,
|
||||||
transm_parser_payload);
|
rule, transm_parser_payload);
|
||||||
std::string resolvedPre = MacroExpansion::expand(m_predicate,
|
std::string resolvedPre = MacroExpansion::expand(m_predicate,
|
||||||
transm_parser_payload);
|
rule, transm_parser_payload);
|
||||||
|
|
||||||
if (m_operation == setOperation) {
|
if (m_operation == setOperation) {
|
||||||
targetValue = resolvedPre;
|
targetValue = resolvedPre;
|
||||||
|
@ -81,7 +81,6 @@ void Collections::storeOrUpdateFirst(const std::string& collectionName,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tolower(collectionName) == "session"
|
if (tolower(collectionName) == "session"
|
||||||
&& !m_session_collection_key.empty()) {
|
&& !m_session_collection_key.empty()) {
|
||||||
m_session_collection->storeOrUpdateFirst(collectionName + ":"
|
m_session_collection->storeOrUpdateFirst(collectionName + ":"
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
|
|
||||||
#include "src/macro_expansion.h"
|
#include "src/macro_expansion.h"
|
||||||
#include "modsecurity/transaction.h"
|
#include "modsecurity/transaction.h"
|
||||||
|
#include "modsecurity/collection/variable.h"
|
||||||
|
#include "src/variables/rule.h"
|
||||||
|
#include "src/variables/tx.h"
|
||||||
|
#include "src/variables/highest_severity.h"
|
||||||
|
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
|
|
||||||
@ -35,8 +40,15 @@ std::string MacroExpansion::expandKeepOriginal(const std::string& input,
|
|||||||
|
|
||||||
std::string MacroExpansion::expand(const std::string& input,
|
std::string MacroExpansion::expand(const std::string& input,
|
||||||
Transaction *transaction) {
|
Transaction *transaction) {
|
||||||
|
return expand(input, NULL, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string MacroExpansion::expand(const std::string& input,
|
||||||
|
modsecurity::Rule *rule, Transaction *transaction) {
|
||||||
std::string res;
|
std::string res;
|
||||||
size_t pos = input.find("%{");
|
size_t pos = input.find("%{");
|
||||||
|
std::string v;
|
||||||
|
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
res = input;
|
res = input;
|
||||||
@ -59,7 +71,27 @@ std::string MacroExpansion::expand(const std::string& input,
|
|||||||
std::string col = std::string(variable, 0, collection);
|
std::string col = std::string(variable, 0, collection);
|
||||||
std::string var = std::string(variable, collection + 1,
|
std::string var = std::string(variable, collection + 1,
|
||||||
variable.length() - (collection + 1));
|
variable.length() - (collection + 1));
|
||||||
variableValue = transaction->m_collections.resolveFirst(col, var);
|
|
||||||
|
if (col == "RULE") {
|
||||||
|
if (rule == NULL) {
|
||||||
|
transaction->debug(9, "macro expansion: cannot resolve " \
|
||||||
|
"RULE variable without the Rule object");
|
||||||
|
goto ops;
|
||||||
|
}
|
||||||
|
modsecurity::Variables::Rule r("RULE:" + var);
|
||||||
|
std::vector<const collection::Variable *> l;
|
||||||
|
r.evaluateInternal(transaction, rule, &l);
|
||||||
|
if (l.size() > 0) {
|
||||||
|
v = l[0]->m_value;
|
||||||
|
variableValue = &v;
|
||||||
|
}
|
||||||
|
for (auto *i : l) {
|
||||||
|
delete i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
variableValue = transaction->m_collections.resolveFirst(col,
|
||||||
|
var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.erase(start, end - start + 1);
|
res.erase(start, end - start + 1);
|
||||||
@ -70,7 +102,7 @@ std::string MacroExpansion::expand(const std::string& input,
|
|||||||
if (variableValue != NULL) {
|
if (variableValue != NULL) {
|
||||||
res.insert(start, *variableValue);
|
res.insert(start, *variableValue);
|
||||||
}
|
}
|
||||||
|
ops:
|
||||||
pos = res.find("%{");
|
pos = res.find("%{");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ class MacroExpansion {
|
|||||||
|
|
||||||
static std::string expand(const std::string& input,
|
static std::string expand(const std::string& input,
|
||||||
Transaction *transaction);
|
Transaction *transaction);
|
||||||
|
static std::string expand(const std::string& input,
|
||||||
|
modsecurity::Rule *r, Transaction *transaction);
|
||||||
static std::string expandKeepOriginal(const std::string& input,
|
static std::string expandKeepOriginal(const std::string& input,
|
||||||
Transaction *transaction);
|
Transaction *transaction);
|
||||||
};
|
};
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "src/actions/xmlns.h"
|
#include "src/actions/xmlns.h"
|
||||||
#include "src/actions/log_data.h"
|
#include "src/actions/log_data.h"
|
||||||
#include "src/actions/msg.h"
|
#include "src/actions/msg.h"
|
||||||
|
#include "src/utils.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace Variables {
|
namespace Variables {
|
||||||
@ -52,6 +53,7 @@ void Rule::evaluateInternal(Transaction *t,
|
|||||||
modsecurity::Rule *rule,
|
modsecurity::Rule *rule,
|
||||||
std::vector<const collection::Variable *> *l) {
|
std::vector<const collection::Variable *> *l) {
|
||||||
std::map<std::string, std::string> envs;
|
std::map<std::string, std::string> envs;
|
||||||
|
std::string m_name_upper = toupper(m_name);
|
||||||
|
|
||||||
// id
|
// id
|
||||||
envs.insert(std::pair<std::string, std::string>("RULE:id",
|
envs.insert(std::pair<std::string, std::string>("RULE:id",
|
||||||
@ -86,14 +88,17 @@ void Rule::evaluateInternal(Transaction *t,
|
|||||||
for (actions::Action *i : acts) {
|
for (actions::Action *i : acts) {
|
||||||
actions::Msg *a = reinterpret_cast<actions::Msg *>(i);
|
actions::Msg *a = reinterpret_cast<actions::Msg *>(i);
|
||||||
if (a) {
|
if (a) {
|
||||||
|
std::string data = a->data(t);
|
||||||
envs.insert(std::pair<std::string, std::string>("RULE:msg",
|
envs.insert(std::pair<std::string, std::string>("RULE:msg",
|
||||||
a->data(t)));
|
data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& x : envs) {
|
for (auto& x : envs) {
|
||||||
if ((x.first.substr(0, m_name.size() + 1).compare(m_name + ":") != 0)
|
std::string xup = toupper(x.first);
|
||||||
&& (x.first != m_name)) {
|
if ((xup.substr(0, m_name_upper.size() + 1)
|
||||||
|
.compare(m_name_upper + ":") != 0)
|
||||||
|
&& (xup != m_name_upper)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
l->push_back(new collection::Variable(x.first, x.second));
|
l->push_back(new collection::Variable(x.first, x.second));
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"enabled":1,
|
"enabled":1,
|
||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Variables :: RULE (1/5)",
|
"title":"Testing Variables :: RULE (1/7)",
|
||||||
"client":{
|
"client":{
|
||||||
"ip":"200.249.12.31",
|
"ip":"200.249.12.31",
|
||||||
"port":123
|
"port":123
|
||||||
@ -48,7 +48,7 @@
|
|||||||
{
|
{
|
||||||
"enabled":1,
|
"enabled":1,
|
||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Variables :: RULE (2/5)",
|
"title":"Testing Variables :: RULE (2/7)",
|
||||||
"client":{
|
"client":{
|
||||||
"ip":"200.249.12.31",
|
"ip":"200.249.12.31",
|
||||||
"port":123
|
"port":123
|
||||||
@ -94,7 +94,7 @@
|
|||||||
{
|
{
|
||||||
"enabled":1,
|
"enabled":1,
|
||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Variables :: RULE (3/5)",
|
"title":"Testing Variables :: RULE (3/7)",
|
||||||
"client":{
|
"client":{
|
||||||
"ip":"200.249.12.31",
|
"ip":"200.249.12.31",
|
||||||
"port":123
|
"port":123
|
||||||
@ -140,7 +140,7 @@
|
|||||||
{
|
{
|
||||||
"enabled":1,
|
"enabled":1,
|
||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Variables :: RULE (4/5)",
|
"title":"Testing Variables :: RULE (4/7)",
|
||||||
"client":{
|
"client":{
|
||||||
"ip":"200.249.12.31",
|
"ip":"200.249.12.31",
|
||||||
"port":123
|
"port":123
|
||||||
@ -186,7 +186,7 @@
|
|||||||
{
|
{
|
||||||
"enabled":1,
|
"enabled":1,
|
||||||
"version_min":300000,
|
"version_min":300000,
|
||||||
"title":"Testing Variables :: RULE (5/5)",
|
"title":"Testing Variables :: RULE (5/7)",
|
||||||
"client":{
|
"client":{
|
||||||
"ip":"200.249.12.31",
|
"ip":"200.249.12.31",
|
||||||
"port":123
|
"port":123
|
||||||
@ -228,6 +228,98 @@
|
|||||||
"SecDebugLogLevel 9",
|
"SecDebugLogLevel 9",
|
||||||
"SecRule RULE:msg \"@contains test\" \"id:1,msg:'message123',phase:3,pass,t:trim\""
|
"SecRule RULE:msg \"@contains test\" \"id:1,msg:'message123',phase:3,pass,t:trim\""
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Variables :: RULE (6/7)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length": "27",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"method":"POST",
|
||||||
|
"body": [
|
||||||
|
"param1=value1¶m2=value2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":" Target value: \"message123\" \\(Variable: RULE:msg\\)"
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecDebugLog \/tmp\/modsec_debug.log",
|
||||||
|
"SecDebugLogLevel 9",
|
||||||
|
"SecRule rule:msg \"@contains test\" \"id:1,msg:'message123',phase:3,pass,t:trim\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Variables :: RULE (7/7)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length": "27",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"method":"POST",
|
||||||
|
"body": [
|
||||||
|
"param1=value1¶m2=value2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":"Saving variable: IP:block_reason with value: message123"
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecDebugLog \/tmp\/modsec_debug.log",
|
||||||
|
"SecDebugLogLevel 9",
|
||||||
|
"SecRule rule:msg \"@contains message\" \"id:1,setvar:'ip.block_reason=%{RULE.msg}%',msg:'message123',phase:3,pass,t:trim\""
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user