mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Looks for external resources in the same path of the rule
This commit is contained in:
parent
5cc9e94505
commit
e54ef72051
@ -23,7 +23,8 @@ namespace ModSecurity {
|
||||
namespace operators {
|
||||
|
||||
|
||||
bool IpMatchFromFile::init(const char **error) {
|
||||
bool IpMatchFromFile::init(const std::string &file,
|
||||
const char **error) {
|
||||
std::string e("");
|
||||
bool res = false;
|
||||
|
||||
|
@ -29,7 +29,7 @@ class IpMatchFromFile : public IpMatch {
|
||||
IpMatchFromFile(std::string op, std::string param, bool negation)
|
||||
: IpMatch(op, param, negation) { }
|
||||
|
||||
bool init(const char **error) override;
|
||||
bool init(const std::string& file, const char **error) override;
|
||||
};
|
||||
|
||||
} // namespace operators
|
||||
|
@ -40,7 +40,10 @@ class Operator {
|
||||
std::string param;
|
||||
bool negation;
|
||||
|
||||
virtual bool init(const char **error) { return true; }
|
||||
virtual bool init(const std::string &file, const char **error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool evaluate(Assay *assay);
|
||||
virtual bool evaluate(Assay *assay, const std::string &str);
|
||||
static Operator *instantiate(std::string op);
|
||||
|
@ -19,12 +19,13 @@
|
||||
|
||||
#include "operators/operator.h"
|
||||
#include "utils/https_client.h"
|
||||
#include "src/utils.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
namespace operators {
|
||||
|
||||
|
||||
bool PmFromFile::init(const char **error) {
|
||||
bool PmFromFile::init(const std::string &config, const char **error) {
|
||||
std::istream *iss;
|
||||
|
||||
if (param.compare(0, 8, "https://") == 0) {
|
||||
@ -36,7 +37,8 @@ bool PmFromFile::init(const char **error) {
|
||||
}
|
||||
iss = new std::stringstream(client.content);
|
||||
} else {
|
||||
iss = new std::ifstream(param, std::ios::in);
|
||||
std::string resource = find_resource(param, config);
|
||||
iss = new std::ifstream(resource, std::ios::in);
|
||||
|
||||
if (((std::ifstream *)iss)->is_open() == false) {
|
||||
*error = std::string("Failed to open file: " + param).c_str();
|
||||
|
@ -31,7 +31,7 @@ class PmFromFile : public Pm {
|
||||
PmFromFile(std::string op, std::string param, bool negation)
|
||||
: Pm(op, param, negation) { }
|
||||
|
||||
bool init(const char **error) override;
|
||||
bool init(const std::string &file, const char **error) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ bool Rx::evaluate(Assay *assay, const std::string& input) {
|
||||
SMatch match;
|
||||
|
||||
if (regex_search(input, &match, *m_re) && match.size() >= 1) {
|
||||
std::cout << "wheee" << std::endl;
|
||||
// this->matched.push_back(match.match);
|
||||
return true;
|
||||
}
|
||||
|
@ -83,7 +83,8 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
|
||||
}
|
||||
|
||||
|
||||
bool ValidateByteRange::init(const char **error) {
|
||||
bool ValidateByteRange::init(const std::string &file,
|
||||
const char **error) {
|
||||
size_t pos = param.find_first_of(",");
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
|
@ -38,7 +38,7 @@ class ValidateByteRange : public Operator {
|
||||
|
||||
bool evaluate(Assay *assay, const std::string &input) override;
|
||||
bool getRange(const std::string &rangeRepresentation, const char **error);
|
||||
bool init(const char **error) override;
|
||||
bool init(const std::string& file, const char **error) override;
|
||||
private:
|
||||
std::vector<std::string> ranges;
|
||||
char table[32];
|
||||
|
@ -90,7 +90,9 @@ int Driver::addSecRule(Rule *rule) {
|
||||
* by other rule
|
||||
*/
|
||||
if (rule->rule_id == 0) {
|
||||
parserError << "Rules must have an ID." << std::endl;
|
||||
parserError << "Rules must have an ID. File: ";
|
||||
parserError << rule->m_fileName << " at line: ";
|
||||
parserError << std::to_string(rule->m_lineNumber) << std::endl;
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) {
|
||||
|
@ -351,7 +351,7 @@ op:
|
||||
{
|
||||
Operator *op = Operator::instantiate($1);
|
||||
const char *error = NULL;
|
||||
if (op->init(&error) == false) {
|
||||
if (op->init(driver.ref.back(), &error) == false) {
|
||||
driver.error(@0, error);
|
||||
YYERROR;
|
||||
}
|
||||
@ -361,7 +361,7 @@ op:
|
||||
{
|
||||
Operator *op = Operator::instantiate("\"@rx " + $1 + "\"");
|
||||
const char *error = NULL;
|
||||
if (op->init(&error) == false) {
|
||||
if (op->init(driver.ref.back(), &error) == false) {
|
||||
driver.error(@0, error);
|
||||
YYERROR;
|
||||
}
|
||||
@ -375,7 +375,9 @@ expression:
|
||||
Rule *rule = new Rule(
|
||||
/* op */ $3,
|
||||
/* variables */ $2,
|
||||
/* actions */ $4
|
||||
/* actions */ $4,
|
||||
/* file name */ driver.ref.back(),
|
||||
/* line number */ @0.end.line
|
||||
);
|
||||
|
||||
if (driver.addSecRule(rule) == false) {
|
||||
@ -387,7 +389,9 @@ expression:
|
||||
Rule *rule = new Rule(
|
||||
/* op */ $3,
|
||||
/* variables */ $2,
|
||||
/* actions */ NULL
|
||||
/* actions */ NULL,
|
||||
/* file name */ driver.ref.back(),
|
||||
/* line number */ @0.end.line
|
||||
);
|
||||
|
||||
if (driver.addSecRule(rule) == false) {
|
||||
@ -399,7 +403,9 @@ expression:
|
||||
Rule *rule = new Rule(
|
||||
/* op */ NULL,
|
||||
/* variables */ NULL,
|
||||
/* actions */ $2
|
||||
/* actions */ $2,
|
||||
/* file name */ driver.ref.back(),
|
||||
/* line number */ @0.end.line
|
||||
);
|
||||
driver.addSecAction(rule);
|
||||
}
|
||||
@ -508,7 +514,14 @@ expression:
|
||||
/* Debug log: end */
|
||||
| CONFIG_DIR_GEO_DB
|
||||
{
|
||||
GeoLookup::getInstance().setDataBase($1);
|
||||
std::string file = ModSecurity::find_resource($1, driver.ref.back());
|
||||
if (GeoLookup::getInstance().setDataBase(file) == false) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to load the GeoDB from: ";
|
||||
ss << file;
|
||||
driver.error(@0, ss.str());
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
/* Body limits */
|
||||
| CONFIG_DIR_REQ_BODY_LIMIT
|
||||
|
@ -98,7 +98,7 @@ CONFIG_SEC_REMOTE_RULES (?i:SecRemoteRules)
|
||||
CONFIG_SEC_REMOTE_RULES_FAIL_ACTION (?i:SecRemoteRulesFailAction)
|
||||
|
||||
|
||||
DICT_ELEMENT [^ \|\t]+
|
||||
DICT_ELEMENT [^ \t]+
|
||||
|
||||
|
||||
OPERATOR (?i:(?:@inspectFile|@fuzzyHash|@validateByteRange|@validateDTD|@validateHash|@validateSchema|@verifyCC|@verifyCPF|@verifySSN|@gsbLookup|@rsub)|(?:\!{0,1})(?:@within|@containsWord|@contains|@endsWith|@eq|@ge|@gt|@ipMatchF|@ipMatch|@ipMatchFromFile|@le|@lt|@pmf|@pm|@pmFromFile|@rbl|@rx|@streq|@strmatch|@beginsWith))
|
||||
@ -143,17 +143,20 @@ CONFIG_VALUE_PATH [0-9A-Za-z_/\.\-\*]+
|
||||
AUDIT_PARTS [ABCDEFHJKIZ]+
|
||||
CONFIG_VALUE_NUMBER [0-9]+
|
||||
|
||||
FREE_TEXT ([^\"]|([^\\]\\\"))+
|
||||
FREE_TEXT ([^\"]|(\\\"))+
|
||||
|
||||
FREE_TEXT_NEW_LINE [^\"|\n]+
|
||||
FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+
|
||||
FREE_TEXT_SPACE [^ \t]+
|
||||
FREE_TEXT_SPACE_COMMA [^, \t]+
|
||||
FREE_TEXT_SPACE_COMMA_QUOTE [^, \t\"]+
|
||||
|
||||
VAR_FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+
|
||||
VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+
|
||||
VAR_FREE_TEXT_SPACE [^ \t\"]+
|
||||
|
||||
SOMETHING ["]{1}[^@]{1}([^"]|([^\\"]\\\"))*["]{1}
|
||||
|
||||
CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
|
||||
|
||||
%x EXPECTING_OPERATOR COMMENT
|
||||
@ -266,14 +269,14 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
|
||||
{CONFIG_DIR_SEC_MARKER}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }
|
||||
|
||||
<EXPECTING_OPERATOR>{
|
||||
["][^@]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_FREE_TEXT(yytext, *driver.loc.back()); }
|
||||
{SOMETHING} { BEGIN(INITIAL); return yy::seclang_parser::make_FREE_TEXT(yytext, *driver.loc.back()); }
|
||||
["]{OPERATOR}[ ]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
|
||||
["]{OPERATORNOARG}[\t ]*["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
|
||||
}
|
||||
|
||||
{ACTION} { return yy::seclang_parser::make_ACTION(yytext, *driver.loc.back()); }
|
||||
{ACTION_PHASE} { return yy::seclang_parser::make_ACTION_PHASE(yytext, *driver.loc.back()); }
|
||||
{ACTION_SKIP_AFTER}:{FREE_TEXT} { return yy::seclang_parser::make_ACTION_SKIP_AFTER(strchr(yytext, ':') + 1, *driver.loc.back()); }
|
||||
{ACTION_SKIP_AFTER}:{FREE_TEXT_SPACE_COMMA_QUOTE} { return yy::seclang_parser::make_ACTION_SKIP_AFTER(strchr(yytext, ':') + 1, *driver.loc.back()); }
|
||||
{ACTION_AUDIT_LOG} { return yy::seclang_parser::make_ACTION_AUDIT_LOG(yytext, *driver.loc.back()); }
|
||||
|
||||
{ACTION_SEVERITY}:{ACTION_SEVERITY_VALUE} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext + 9, *driver.loc.back()); }
|
||||
|
13
src/rule.cc
13
src/rule.cc
@ -82,12 +82,15 @@ Rule::Rule(std::string marker)
|
||||
m_unconditional(false),
|
||||
m_secmarker(true),
|
||||
m_marker(marker),
|
||||
m_referenceCount(0) { }
|
||||
m_referenceCount(0),
|
||||
m_fileName(""),
|
||||
m_lineNumber(0) { }
|
||||
|
||||
Rule::Rule(Operator *_op,
|
||||
std::vector<Variable *> *_variables,
|
||||
std::vector<Action *> *actions)
|
||||
: chained(false),
|
||||
std::vector<Action *> *actions,
|
||||
std::string fileName,
|
||||
int lineNumber): chained(false),
|
||||
chainedRule(NULL),
|
||||
variables(_variables),
|
||||
op(_op),
|
||||
@ -96,7 +99,9 @@ Rule::Rule(Operator *_op,
|
||||
m_unconditional(false),
|
||||
m_secmarker(false),
|
||||
m_marker(""),
|
||||
m_referenceCount(0) {
|
||||
m_referenceCount(0),
|
||||
m_fileName(fileName),
|
||||
m_lineNumber(lineNumber) {
|
||||
if (actions != NULL) {
|
||||
for (Action *a : *actions) {
|
||||
if (a->action_kind == Action::ConfigurationKind) {
|
||||
|
@ -33,7 +33,10 @@ class Rule {
|
||||
public:
|
||||
Rule(operators::Operator *_op,
|
||||
std::vector<Variables::Variable *> *_variables,
|
||||
std::vector<actions::Action *> *_actions);
|
||||
std::vector<actions::Action *> *_actions,
|
||||
std::string fileName,
|
||||
int lineNumber
|
||||
);
|
||||
explicit Rule(std::string marker);
|
||||
|
||||
~Rule();
|
||||
@ -67,6 +70,8 @@ class Rule {
|
||||
|
||||
std::string m_marker;
|
||||
bool m_secmarker;
|
||||
std::string m_fileName;
|
||||
int m_lineNumber;
|
||||
|
||||
private:
|
||||
bool m_unconditional;
|
||||
|
33
src/utils.cc
33
src/utils.cc
@ -1040,5 +1040,38 @@ std::vector<std::string> expandEnv(const std::string& var, int flags)
|
||||
}
|
||||
|
||||
|
||||
std::string get_path(const std::string& file) {
|
||||
size_t found;
|
||||
|
||||
found = file.find_last_of("/\\");
|
||||
if (found > 0) {
|
||||
return file.substr(0, found);
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
std::string find_resource(const std::string& resource, const std::string& config) {
|
||||
std::ifstream *iss = NULL;
|
||||
|
||||
// Trying absolute or relative to the current dir.
|
||||
iss = new std::ifstream(resource, std::ios::in);
|
||||
if (iss->is_open()) {
|
||||
iss->close();
|
||||
return resource;
|
||||
}
|
||||
|
||||
// Trying the same path of the configuration file.
|
||||
std::string f = get_path(config) + "/" + resource;
|
||||
iss = new std::ifstream(f, std::ios::in);
|
||||
if (iss->is_open()) {
|
||||
iss->close();
|
||||
return f;
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
} // namespace ModSecurity
|
||||
|
||||
|
@ -48,6 +48,8 @@ namespace ModSecurity {
|
||||
std::string limitTo(int amount, const std::string &str);
|
||||
std::string toHexIfNeeded(const std::string &str);
|
||||
std::vector<std::string> expandEnv(const std::string& var, int flags);
|
||||
std::string find_resource(const std::string& file,
|
||||
const std::string& param);
|
||||
} // namespace ModSecurity
|
||||
|
||||
#define SRC_UTILS_H_
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
include "owasp-modsecurity-crs-orig/modsecurity_crs_10_setup.conf"
|
||||
#include "owasp-modsecurity-crs-orig/rules/*.conf"
|
||||
#include owasp-modsecurity-crs-orig/rules/RESPONSE-51-DATA-LEAKAGES-SQL.conf
|
||||
include owasp-modsecurity-crs-orig/rules/REQUEST-01-COMMON-EXCEPTIONS.conf
|
||||
include owasp-modsecurity-crs-orig/rules/REQUEST-10-IP-REPUTATION.conf
|
||||
include owasp-modsecurity-crs-orig/rules/REQUEST-11-METHOD-ENFORCEMENT.conf
|
||||
|
@ -51,7 +51,7 @@ void perform_unit_test(UnitTest *t, ModSecurityTestResults<UnitTest>* res) {
|
||||
if (t->type == "op") {
|
||||
Operator *op = Operator::instantiate("\"@" + t->name + \
|
||||
" " + t->param + "\"");
|
||||
op->init(&error);
|
||||
op->init(t->filename, &error);
|
||||
int ret = op->evaluate(NULL, t->input);
|
||||
if (ret != t->ret) {
|
||||
t->obtained = ret;
|
||||
|
Loading…
x
Reference in New Issue
Block a user