mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Adds support to macro expansion in setvar action
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "modsecurity/assay.h"
|
||||
#include "src/rule.h"
|
||||
#include "src/macro_expansion.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
namespace actions {
|
||||
@@ -94,6 +95,7 @@ void SetVar::dump() {
|
||||
bool SetVar::evaluate(Rule *rule, Assay *assay) {
|
||||
std::string targetValue;
|
||||
|
||||
variableName = MacroExpansion::expand(variableName, assay);
|
||||
int value = 0;
|
||||
try {
|
||||
std::string *resolvedValue =
|
||||
@@ -111,14 +113,16 @@ bool SetVar::evaluate(Rule *rule, Assay *assay) {
|
||||
try {
|
||||
pre = stoi(predicate);
|
||||
} catch (...) {
|
||||
/* perform a macro expansion. */
|
||||
pre = 0;
|
||||
try {
|
||||
pre = stoi(MacroExpansion::expand(predicate, assay));
|
||||
} catch (...) {
|
||||
pre = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case setOperation:
|
||||
/* perform a macro expansion. */
|
||||
targetValue = predicate;
|
||||
targetValue = MacroExpansion::expand(predicate, assay);
|
||||
break;
|
||||
case sumAndSetOperation:
|
||||
targetValue = std::to_string(value + pre);
|
||||
|
@@ -1374,8 +1374,9 @@ std::string* Assay::resolve_variable_first(std::string var) {
|
||||
std::string* Assay::resolve_variable_first(const std::string collectionName,
|
||||
std::string var) {
|
||||
for (auto &a : collections) {
|
||||
if (a.first == collectionName) {
|
||||
auto range = a.second->equal_range(collectionName + ":" + var);
|
||||
if (tolower(a.first) == tolower(collectionName)) {
|
||||
auto range = a.second->equal_range(toupper(collectionName)
|
||||
+ ":" + var);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
return &it->second;
|
||||
}
|
||||
@@ -1391,8 +1392,8 @@ void Assay::setCollection(const std::string& collectionName,
|
||||
ModSecurityStringVariables *collection;
|
||||
|
||||
try {
|
||||
collection = collections.at(collectionName);
|
||||
collection->storeOrUpdateVariable(collectionName + ":"
|
||||
collection = collections.at(toupper(collectionName));
|
||||
collection->storeOrUpdateVariable(toupper(collectionName) + ":"
|
||||
+ variableName, targetValue);
|
||||
} catch (...) {
|
||||
debug(9, "don't know any collection named: "
|
||||
|
@@ -14,10 +14,43 @@
|
||||
*/
|
||||
|
||||
#include "src/macro_expansion.h"
|
||||
#include "modsecurity/assay.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
MacroExpansion::MacroExpansion() {
|
||||
MacroExpansion::MacroExpansion() { }
|
||||
|
||||
std::string MacroExpansion::expand(const std::string& input, Assay *assay) {
|
||||
std::string res(input);
|
||||
|
||||
size_t pos = res.find("%{");
|
||||
while (pos != std::string::npos) {
|
||||
size_t start = pos;
|
||||
size_t end = res.find("}%");
|
||||
if (end == std::string::npos) {
|
||||
return res;
|
||||
}
|
||||
std::string variable(res, start + 2, end - (start + 2));
|
||||
std::string *variableValue;
|
||||
size_t collection = variable.find(".");
|
||||
if (collection == std::string::npos) {
|
||||
variableValue = assay->resolve_variable_first(variable);
|
||||
} else {
|
||||
std::string col = std::string(variable, 0, collection);
|
||||
std::string var = std::string(variable, collection + 1,
|
||||
variable.length() - (collection + 1));
|
||||
variableValue = assay->resolve_variable_first(col, var);
|
||||
}
|
||||
|
||||
res.erase(start, end + 2);
|
||||
if (variableValue != NULL) {
|
||||
res.insert(start, *variableValue);
|
||||
}
|
||||
|
||||
pos = res.find("%{");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace ModSecurity
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "modsecurity/modsecurity.h"
|
||||
#include "modsecurity/assay.h"
|
||||
|
||||
#ifndef SRC_MACRO_EXPANSION_H_
|
||||
#define SRC_MACRO_EXPANSION_H_
|
||||
@@ -29,6 +30,8 @@ namespace ModSecurity {
|
||||
class MacroExpansion {
|
||||
public:
|
||||
MacroExpansion();
|
||||
|
||||
static std::string expand(const std::string& input, Assay *assay);
|
||||
};
|
||||
|
||||
|
||||
|
10
src/utils.cc
10
src/utils.cc
@@ -112,6 +112,16 @@ std::string tolower(std::string str) {
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string toupper(std::string str) {
|
||||
std::locale loc;
|
||||
std::string value;
|
||||
|
||||
for (std::string::size_type i=0; i < str.length(); ++i) {
|
||||
value.assign(value + std::toupper(str[i], loc));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
const char SAFE[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
|
@@ -32,6 +32,7 @@ namespace ModSecurity {
|
||||
void chomp(std::string *str);
|
||||
std::string uri_decode(const std::string & sSrc);
|
||||
std::string tolower(std::string str);
|
||||
std::string toupper(std::string str);
|
||||
double cpu_seconds(void);
|
||||
int js_decode_nonstrict_inplace(unsigned char *input, int64_t input_len);
|
||||
static unsigned char x2c(unsigned char *what);
|
||||
|
Reference in New Issue
Block a user