mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Adds support to config warnings
This commit is contained in:
parent
bf87f11036
commit
62d35fbf97
@ -127,6 +127,7 @@ TESTS+=test/test-cases/regression/config-body_limits.json
|
|||||||
TESTS+=test/test-cases/regression/config-calling_phases_by_name.json
|
TESTS+=test/test-cases/regression/config-calling_phases_by_name.json
|
||||||
TESTS+=test/test-cases/regression/config-include-bad.json
|
TESTS+=test/test-cases/regression/config-include-bad.json
|
||||||
TESTS+=test/test-cases/regression/config-include.json
|
TESTS+=test/test-cases/regression/config-include.json
|
||||||
|
TESTS+=test/test-cases/regression/config-warning.json
|
||||||
TESTS+=test/test-cases/regression/config-remove_by_id.json
|
TESTS+=test/test-cases/regression/config-remove_by_id.json
|
||||||
TESTS+=test/test-cases/regression/config-remove_by_msg.json
|
TESTS+=test/test-cases/regression/config-remove_by_msg.json
|
||||||
TESTS+=test/test-cases/regression/config-remove_by_tag.json
|
TESTS+=test/test-cases/regression/config-remove_by_tag.json
|
||||||
|
@ -97,6 +97,7 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const char *error = NULL;
|
const char *error = NULL;
|
||||||
|
const char *warn = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int f;
|
int f;
|
||||||
@ -108,7 +109,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
rules = msc_create_rules_set();
|
rules = msc_create_rules_set();
|
||||||
|
|
||||||
ret = msc_rules_add_file(rules, main_rule_uri, &error);
|
ret = msc_rules_add_file(rules, main_rule_uri, &warn, &error);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Problems loading the rules --\n");
|
fprintf(stderr, "Problems loading the rules --\n");
|
||||||
fprintf(stderr, "%s\n", error);
|
fprintf(stderr, "%s\n", error);
|
||||||
|
@ -27,6 +27,7 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const char *error = NULL;
|
const char *error = NULL;
|
||||||
|
const char *warn = NULL;
|
||||||
ModSecurity *modsec;
|
ModSecurity *modsec;
|
||||||
Transaction *transaction = NULL;
|
Transaction *transaction = NULL;
|
||||||
RulesSet *rules;
|
RulesSet *rules;
|
||||||
@ -38,7 +39,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
rules = msc_create_rules_set();
|
rules = msc_create_rules_set();
|
||||||
|
|
||||||
ret = msc_rules_add_file(rules, main_rule_uri, &error);
|
ret = msc_rules_add_file(rules, main_rule_uri, &warn, &error);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Problems loading the rules --\n");
|
fprintf(stderr, "Problems loading the rules --\n");
|
||||||
fprintf(stderr, "%s\n", error);
|
fprintf(stderr, "%s\n", error);
|
||||||
@ -48,7 +49,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
ret = msc_rules_add_remote(rules, "test",
|
ret = msc_rules_add_remote(rules, "test",
|
||||||
"https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt",
|
"https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt",
|
||||||
&error);
|
&warn, &error);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Problems loading the rules --\n");
|
fprintf(stderr, "Problems loading the rules --\n");
|
||||||
fprintf(stderr, "%s\n", error);
|
fprintf(stderr, "%s\n", error);
|
||||||
|
@ -120,6 +120,19 @@ class Action {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ActionNotSupported : public Action {
|
||||||
|
public:
|
||||||
|
ActionNotSupported() : Action()
|
||||||
|
{ };
|
||||||
|
|
||||||
|
explicit ActionNotSupported(const std::string& action)
|
||||||
|
: Action(action)
|
||||||
|
{ };
|
||||||
|
|
||||||
|
ActionNotSupported(const ActionNotSupported &other) = delete;
|
||||||
|
ActionNotSupported &operator=(const ActionNotSupported& a) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace actions
|
} // namespace actions
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
|
@ -75,6 +75,7 @@ class RulesSet : public RulesSetProperties {
|
|||||||
int evaluate(int phase, Transaction *transaction);
|
int evaluate(int phase, Transaction *transaction);
|
||||||
|
|
||||||
std::string getParserError();
|
std::string getParserError();
|
||||||
|
std::string getParserWarnings();
|
||||||
|
|
||||||
void debug(int level, const std::string &id, const std::string &uri,
|
void debug(int level, const std::string &id, const std::string &uri,
|
||||||
const std::string &msg);
|
const std::string &msg);
|
||||||
@ -95,11 +96,14 @@ extern "C" {
|
|||||||
|
|
||||||
RulesSet *msc_create_rules_set(void);
|
RulesSet *msc_create_rules_set(void);
|
||||||
void msc_rules_dump(RulesSet *rules);
|
void msc_rules_dump(RulesSet *rules);
|
||||||
int msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from, const char **error);
|
int msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from,
|
||||||
|
const char **warn, const char **error);
|
||||||
int msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri,
|
int msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri,
|
||||||
const char **error);
|
const char **warn, const char **error);
|
||||||
int msc_rules_add_file(RulesSet *rules, const char *file, const char **error);
|
int msc_rules_add_file(RulesSet *rules, const char *file,
|
||||||
int msc_rules_add(RulesSet *rules, const char *plain_rules, const char **error);
|
const char **warn, const char **error);
|
||||||
|
int msc_rules_add(RulesSet *rules, const char *plain_rules,
|
||||||
|
const char **warn, const char **error);
|
||||||
int msc_rules_cleanup(RulesSet *rules);
|
int msc_rules_cleanup(RulesSet *rules);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -457,6 +457,7 @@ class RulesSetProperties {
|
|||||||
RulesExceptions m_exceptions;
|
RulesExceptions m_exceptions;
|
||||||
std::list<std::string> m_components;
|
std::list<std::string> m_components;
|
||||||
std::ostringstream m_parserError;
|
std::ostringstream m_parserError;
|
||||||
|
std::ostringstream m_parserWarn;
|
||||||
ConfigSet m_responseBodyTypeToBeInspected;
|
ConfigSet m_responseBodyTypeToBeInspected;
|
||||||
ConfigString m_httpblKey;
|
ConfigString m_httpblKey;
|
||||||
ConfigString m_uploadDirectory;
|
ConfigString m_uploadDirectory;
|
||||||
|
@ -180,7 +180,7 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
|
|||||||
*/
|
*/
|
||||||
if (rule->getId() == 0) {
|
if (rule->getId() == 0) {
|
||||||
m_parserError << "Rules must have an ID. File: ";
|
m_parserError << "Rules must have an ID. File: ";
|
||||||
m_parserError << rule->getFileName() << " at line: ";
|
m_parserError << *rule->getFileName() << " at line: ";
|
||||||
m_parserError << std::to_string(rule->getLineNumber()) << std::endl;
|
m_parserError << std::to_string(rule->getLineNumber()) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -282,5 +282,30 @@ void Driver::error(const yy::location& l, const std::string& m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Driver::warn(const yy::location& l, const std::string& m) {
|
||||||
|
warn(l, m, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Driver::warn(const yy::location& l, const std::string& m,
|
||||||
|
const std::string& c) {
|
||||||
|
if (m_parserWarn.tellp() != 0) {
|
||||||
|
m_parserWarn << std::endl;
|
||||||
|
}
|
||||||
|
m_parserWarn << "Warning. ";
|
||||||
|
m_parserWarn << "File: " << *l.end.filename << ". ";
|
||||||
|
m_parserWarn << "Line: " << l.end.line << ". ";
|
||||||
|
m_parserWarn << "Column: " << l.end.column - 1 << ". ";
|
||||||
|
|
||||||
|
if (m.empty() == false) {
|
||||||
|
m_parserWarn << "" << m << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.empty() == false) {
|
||||||
|
m_parserWarn << c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Parser
|
} // namespace Parser
|
||||||
} // namespace modsecurity
|
} // namespace modsecurity
|
||||||
|
@ -86,6 +86,10 @@ class Driver : public RulesSetProperties {
|
|||||||
void error(const yy::location& l, const std::string& m,
|
void error(const yy::location& l, const std::string& m,
|
||||||
const std::string& c);
|
const std::string& c);
|
||||||
|
|
||||||
|
void warn(const yy::location& l, const std::string& m);
|
||||||
|
void warn(const yy::location& l, const std::string& m,
|
||||||
|
const std::string& c);
|
||||||
|
|
||||||
std::list<yy::location *> loc;
|
std::list<yy::location *> loc;
|
||||||
|
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -324,7 +324,13 @@ using namespace modsecurity::operators;
|
|||||||
if (t)
|
if (t)
|
||||||
|
|
||||||
|
|
||||||
#define ACTION_NOT_SUPPORTED(a, b) \
|
#define ACTION_NOT_SUPPORTED(a, b, c) \
|
||||||
|
std::unique_ptr<actions::Action> d(new actions::ActionNotSupported(b)); \
|
||||||
|
a = std::move(d); \
|
||||||
|
driver.warn(c, "Action " + std::string(b) + " is not supported in version 3.");
|
||||||
|
|
||||||
|
|
||||||
|
#define ACTION_NOT_SUPPORTED_OLD(a, b) \
|
||||||
driver.error(b, "Action: " + std::string(a) + " is not yet supported."); \
|
driver.error(b, "Action: " + std::string(a) + " is not yet supported."); \
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
||||||
@ -354,7 +360,7 @@ using namespace modsecurity::operators;
|
|||||||
a = std::move(c);
|
a = std::move(c);
|
||||||
|
|
||||||
|
|
||||||
#line 358 "seclang-parser.hh"
|
#line 364 "seclang-parser.hh"
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include <cstdlib> // std::abort
|
# include <cstdlib> // std::abort
|
||||||
@ -488,7 +494,7 @@ using namespace modsecurity::operators;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace yy {
|
namespace yy {
|
||||||
#line 492 "seclang-parser.hh"
|
#line 498 "seclang-parser.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -8629,7 +8635,7 @@ switch (yykind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // yy
|
} // yy
|
||||||
#line 8633 "seclang-parser.hh"
|
#line 8639 "seclang-parser.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,7 +285,13 @@ using namespace modsecurity::operators;
|
|||||||
if (t)
|
if (t)
|
||||||
|
|
||||||
|
|
||||||
#define ACTION_NOT_SUPPORTED(a, b) \
|
#define ACTION_NOT_SUPPORTED(a, b, c) \
|
||||||
|
std::unique_ptr<actions::Action> d(new actions::ActionNotSupported(b)); \
|
||||||
|
a = std::move(d); \
|
||||||
|
driver.warn(c, "Action " + std::string(b) + " is not supported in version 3.");
|
||||||
|
|
||||||
|
|
||||||
|
#define ACTION_NOT_SUPPORTED_OLD(a, b) \
|
||||||
driver.error(b, "Action: " + std::string(a) + " is not yet supported."); \
|
driver.error(b, "Action: " + std::string(a) + " is not yet supported."); \
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
||||||
@ -1285,6 +1291,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_CONN_ENGINE CONFIG_VALUE_OFF
|
| CONFIG_CONN_ENGINE CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecConnEngine is not yet supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_SEC_WEB_APP_ID
|
| CONFIG_SEC_WEB_APP_ID
|
||||||
{
|
{
|
||||||
@ -1308,6 +1316,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_SEC_DISABLE_BACKEND_COMPRESS CONFIG_VALUE_OFF
|
| CONFIG_SEC_DISABLE_BACKEND_COMPRESS CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecDisableBackendCompression is not supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_CONTENT_INJECTION CONFIG_VALUE_ON
|
| CONFIG_CONTENT_INJECTION CONFIG_VALUE_ON
|
||||||
{
|
{
|
||||||
@ -1316,6 +1326,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_CONTENT_INJECTION CONFIG_VALUE_OFF
|
| CONFIG_CONTENT_INJECTION CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecContentInjection is not yet supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_SEC_CHROOT_DIR
|
| CONFIG_SEC_CHROOT_DIR
|
||||||
{
|
{
|
||||||
@ -1329,6 +1341,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_SEC_HASH_ENGINE CONFIG_VALUE_OFF
|
| CONFIG_SEC_HASH_ENGINE CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecHashEngine is not yet supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_SEC_HASH_KEY
|
| CONFIG_SEC_HASH_KEY
|
||||||
{
|
{
|
||||||
@ -1367,6 +1381,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_SEC_INTERCEPT_ON_ERROR CONFIG_VALUE_OFF
|
| CONFIG_SEC_INTERCEPT_ON_ERROR CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecInterceptOnError is not yet supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_SEC_CONN_R_STATE_LIMIT
|
| CONFIG_SEC_CONN_R_STATE_LIMIT
|
||||||
{
|
{
|
||||||
@ -1390,6 +1406,8 @@ expression:
|
|||||||
}
|
}
|
||||||
| CONFIG_SEC_RULE_INHERITANCE CONFIG_VALUE_OFF
|
| CONFIG_SEC_RULE_INHERITANCE CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
|
driver.error(@0, "SecRuleInheritance is not yet supported.");
|
||||||
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONFIG_SEC_RULE_PERF_TIME
|
| CONFIG_SEC_RULE_PERF_TIME
|
||||||
{
|
{
|
||||||
@ -1639,15 +1657,19 @@ expression:
|
|||||||
driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction;
|
driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction;
|
||||||
}
|
}
|
||||||
| CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION
|
| CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION
|
||||||
|
{
|
||||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||||
driver.error(@0, "SecPcreMatchLimitRecursion is not currently supported. Default PCRE values are being used for now");
|
driver.error(@0, "SecPcreMatchLimitRecursion is not currently supported. Default PCRE values are being used for now");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
| CONFIG_DIR_PCRE_MATCH_LIMIT
|
| CONFIG_DIR_PCRE_MATCH_LIMIT
|
||||||
|
{
|
||||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||||
driver.error(@0, "SecPcreMatchLimit is not currently supported. Default PCRE values are being used for now");
|
driver.error(@0, "SecPcreMatchLimit is not currently supported. Default PCRE values are being used for now");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
| CONGIG_DIR_RESPONSE_BODY_MP
|
| CONGIG_DIR_RESPONSE_BODY_MP
|
||||||
{
|
{
|
||||||
std::istringstream buf($1);
|
std::istringstream buf($1);
|
||||||
@ -1677,23 +1699,25 @@ expression:
|
|||||||
| CONGIG_DIR_SEC_TMP_DIR
|
| CONGIG_DIR_SEC_TMP_DIR
|
||||||
{
|
{
|
||||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "As of ModSecurity version 3.0, SecTmpDir is no longer supported.";
|
ss << "As of ModSecurity version 3.0, SecTmpDir is no longer supported.";
|
||||||
ss << " Instead, you can use your web server configurations to control when";
|
ss << " Instead, you can use your web server configurations to control when";
|
||||||
ss << "and where to swap. ModSecurity will follow the web server decision.";
|
ss << "and where to swap. ModSecurity will follow the web server decision.";
|
||||||
driver.error(@0, ss.str());
|
driver.error(@0, ss.str());
|
||||||
YYERROR;
|
YYERROR;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
| CONGIG_DIR_SEC_DATA_DIR
|
| CONGIG_DIR_SEC_DATA_DIR
|
||||||
|
{
|
||||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "SecDataDir is not currently supported.";
|
ss << "SecDataDir is not currently supported.";
|
||||||
ss << " Collections are kept in memory (in_memory-per_process) for now.";
|
ss << " Collections are kept in memory (in_memory-per_process) for now.";
|
||||||
ss << " When using a backend such as LMDB, temp data path is currently defined by the backend.";
|
ss << " When using a backend such as LMDB, temp data path is currently defined by the backend.";
|
||||||
driver.error(@0, ss.str());
|
driver.error(@0, ss.str());
|
||||||
YYERROR;
|
YYERROR;
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
| CONGIG_DIR_SEC_ARG_SEP
|
| CONGIG_DIR_SEC_ARG_SEP
|
||||||
| CONGIG_DIR_SEC_COOKIE_FORMAT
|
| CONGIG_DIR_SEC_COOKIE_FORMAT
|
||||||
{
|
{
|
||||||
@ -1708,10 +1732,12 @@ expression:
|
|||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
| CONGIG_DIR_SEC_STATUS_ENGINE
|
| CONGIG_DIR_SEC_STATUS_ENGINE
|
||||||
|
{
|
||||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||||
driver.error(@0, "SecStatusEngine is not yet supported.");
|
driver.error(@0, "SecStatusEngine is not yet supported.");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
| CONFIG_DIR_UNICODE_MAP_FILE
|
| CONFIG_DIR_UNICODE_MAP_FILE
|
||||||
{
|
{
|
||||||
std::string error;
|
std::string error;
|
||||||
@ -2606,7 +2632,7 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_APPEND
|
| ACTION_APPEND
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("Append", @0);
|
ACTION_NOT_SUPPORTED_OLD("Append", @0);
|
||||||
}
|
}
|
||||||
| ACTION_AUDIT_LOG
|
| ACTION_AUDIT_LOG
|
||||||
{
|
{
|
||||||
@ -2626,18 +2652,15 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_ON
|
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_ON
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
ACTION_NOT_SUPPORTED_OLD("ctl:auditEngine", @0);
|
||||||
//ACTION_CONTAINER($$, new actions::Action($1));
|
|
||||||
}
|
}
|
||||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_OFF
|
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
ACTION_NOT_SUPPORTED_OLD("ctl:auditEngine", @0);
|
||||||
//ACTION_CONTAINER($$, new actions::Action($1));
|
|
||||||
}
|
}
|
||||||
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_RELEVANT_ONLY
|
| ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_RELEVANT_ONLY
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("CtlAuditEngine", @0);
|
ACTION_NOT_SUPPORTED_OLD("ctl:auditEngine", @0);
|
||||||
//ACTION_CONTAINER($$, new actions::Action($1));
|
|
||||||
}
|
}
|
||||||
| ACTION_CTL_AUDIT_LOG_PARTS
|
| ACTION_CTL_AUDIT_LOG_PARTS
|
||||||
{
|
{
|
||||||
@ -2657,13 +2680,11 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_ON
|
| ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_ON
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("CtlForceRequestBodyVariable", @0);
|
ACTION_NOT_SUPPORTED($$, "ctl:forceRequestBodyVariable", @0);
|
||||||
//ACTION_CONTAINER($$, new actions::Action($1));
|
|
||||||
}
|
}
|
||||||
| ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_OFF
|
| ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_OFF
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("CtlForceRequestBodyVariable", @0);
|
ACTION_NOT_SUPPORTED($$, "ctl:forceRequestBodyVariable", @0);
|
||||||
//ACTION_CONTAINER($$, new actions::Action($1));
|
|
||||||
}
|
}
|
||||||
| ACTION_CTL_REQUEST_BODY_ACCESS CONFIG_VALUE_ON
|
| ACTION_CTL_REQUEST_BODY_ACCESS CONFIG_VALUE_ON
|
||||||
{
|
{
|
||||||
@ -2707,7 +2728,7 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_DEPRECATE_VAR
|
| ACTION_DEPRECATE_VAR
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("DeprecateVar", @0);
|
ACTION_NOT_SUPPORTED_OLD("DeprecateVar", @0);
|
||||||
}
|
}
|
||||||
| ACTION_DROP
|
| ACTION_DROP
|
||||||
{
|
{
|
||||||
@ -2763,7 +2784,7 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_PAUSE
|
| ACTION_PAUSE
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("Pause", @0);
|
ACTION_NOT_SUPPORTED_OLD("Pause", @0);
|
||||||
}
|
}
|
||||||
| ACTION_PHASE
|
| ACTION_PHASE
|
||||||
{
|
{
|
||||||
@ -2771,11 +2792,11 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_PREPEND
|
| ACTION_PREPEND
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("Prepend", @0);
|
ACTION_NOT_SUPPORTED_OLD("Prepend", @0);
|
||||||
}
|
}
|
||||||
| ACTION_PROXY
|
| ACTION_PROXY
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("Proxy", @0);
|
ACTION_NOT_SUPPORTED_OLD("Proxy", @0);
|
||||||
}
|
}
|
||||||
| ACTION_REDIRECT run_time_string
|
| ACTION_REDIRECT run_time_string
|
||||||
{
|
{
|
||||||
@ -2787,23 +2808,23 @@ act:
|
|||||||
}
|
}
|
||||||
| ACTION_SANITISE_ARG
|
| ACTION_SANITISE_ARG
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("SanitiseArg", @0);
|
ACTION_NOT_SUPPORTED_OLD("SanitiseArg", @0);
|
||||||
}
|
}
|
||||||
| ACTION_SANITISE_MATCHED
|
| ACTION_SANITISE_MATCHED
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("SanitiseMatched", @0);
|
ACTION_NOT_SUPPORTED_OLD("SanitiseMatched", @0);
|
||||||
}
|
}
|
||||||
| ACTION_SANITISE_MATCHED_BYTES
|
| ACTION_SANITISE_MATCHED_BYTES
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("SanitiseMatchedBytes", @0);
|
ACTION_NOT_SUPPORTED_OLD("SanitiseMatchedBytes", @0);
|
||||||
}
|
}
|
||||||
| ACTION_SANITISE_REQUEST_HEADER
|
| ACTION_SANITISE_REQUEST_HEADER
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("SanitiseRequestHeader", @0);
|
ACTION_NOT_SUPPORTED_OLD("SanitiseRequestHeader", @0);
|
||||||
}
|
}
|
||||||
| ACTION_SANITISE_RESPONSE_HEADER
|
| ACTION_SANITISE_RESPONSE_HEADER
|
||||||
{
|
{
|
||||||
ACTION_NOT_SUPPORTED("SanitiseResponseHeader", @0);
|
ACTION_NOT_SUPPORTED_OLD("SanitiseResponseHeader", @0);
|
||||||
}
|
}
|
||||||
| ACTION_SETENV run_time_string
|
| ACTION_SETENV run_time_string
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,9 @@ RuleWithActions::RuleWithActions(
|
|||||||
std::vector<std::shared_ptr<Action>> newActions;
|
std::vector<std::shared_ptr<Action>> newActions;
|
||||||
if (actions) {
|
if (actions) {
|
||||||
for (auto &a : *actions) {
|
for (auto &a : *actions) {
|
||||||
if (std::dynamic_pointer_cast<ActionTypeRuleMetaData>(a)) {
|
if (std::dynamic_pointer_cast<actions::ActionNotSupported>(a)) {
|
||||||
|
continue;
|
||||||
|
} else if (std::dynamic_pointer_cast<ActionTypeRuleMetaData>(a)) {
|
||||||
confs.push_back(std::dynamic_pointer_cast<ActionTypeRuleMetaData>(a));
|
confs.push_back(std::dynamic_pointer_cast<ActionTypeRuleMetaData>(a));
|
||||||
continue;
|
continue;
|
||||||
} else if (std::dynamic_pointer_cast<ActionDisruptive>(a)) {
|
} else if (std::dynamic_pointer_cast<ActionDisruptive>(a)) {
|
||||||
|
@ -58,6 +58,11 @@ int RulesSet::loadFromUri(const char *uri) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warn = driver->m_parserWarn.str();
|
||||||
|
if (warn.size() > 0) {
|
||||||
|
m_parserWarn << warn;
|
||||||
|
}
|
||||||
|
|
||||||
int rules = this->merge(driver);
|
int rules = this->merge(driver);
|
||||||
delete driver;
|
delete driver;
|
||||||
|
|
||||||
@ -73,12 +78,19 @@ int RulesSet::load(const char *file, const std::string &ref) {
|
|||||||
delete driver;
|
delete driver;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rules = this->merge(driver);
|
int rules = this->merge(driver);
|
||||||
if (rules == -1) {
|
if (rules == -1) {
|
||||||
m_parserError << driver->m_parserError.str();
|
m_parserError << driver->m_parserError.str();
|
||||||
delete driver;
|
delete driver;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warn = driver->m_parserWarn.str();
|
||||||
|
if (warn.size() > 0) {
|
||||||
|
m_parserWarn << warn;
|
||||||
|
}
|
||||||
|
|
||||||
delete driver;
|
delete driver;
|
||||||
|
|
||||||
return rules;
|
return rules;
|
||||||
@ -150,10 +162,14 @@ bool RulesSet::containsDuplicatedIds(RulesWarnings *warning, RulesErrors *error)
|
|||||||
|
|
||||||
|
|
||||||
std::string RulesSet::getParserError() {
|
std::string RulesSet::getParserError() {
|
||||||
return this->m_parserError.str();
|
return m_parserError.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string RulesSet::getParserWarnings() {
|
||||||
|
return m_parserWarn.str();
|
||||||
|
}
|
||||||
|
|
||||||
int RulesSet::evaluate(int phase, Transaction *t) {
|
int RulesSet::evaluate(int phase, Transaction *t) {
|
||||||
if (phase >= modsecurity::Phases::NUMBER_OF_PHASES) {
|
if (phase >= modsecurity::Phases::NUMBER_OF_PHASES) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -344,41 +360,67 @@ extern "C" void msc_rules_dump(RulesSet *rules) {
|
|||||||
|
|
||||||
|
|
||||||
extern "C" int msc_rules_merge(RulesSet *rules_dst,
|
extern "C" int msc_rules_merge(RulesSet *rules_dst,
|
||||||
RulesSet *rules_from, const char **error) {
|
RulesSet *rules_from,
|
||||||
|
const char **warn, const char **error) {
|
||||||
int ret = rules_dst->merge(rules_from);
|
int ret = rules_dst->merge(rules_from);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
*error = strdup(rules_dst->getParserError().c_str());
|
*error = strdup(rules_dst->getParserError().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warnings = rules_dst->getParserWarnings();
|
||||||
|
if (warnings.size() > 0) {
|
||||||
|
*warn = strdup(warnings.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" int msc_rules_add_remote(RulesSet *rules,
|
extern "C" int msc_rules_add_remote(RulesSet *rules,
|
||||||
const char *key, const char *uri, const char **error) {
|
const char *key, const char *uri,
|
||||||
|
const char **warn, const char **error) {
|
||||||
int ret = rules->loadRemote(key, uri);
|
int ret = rules->loadRemote(key, uri);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
*error = strdup(rules->getParserError().c_str());
|
*error = strdup(rules->getParserError().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warnings = rules->getParserWarnings();
|
||||||
|
if (warnings.size() > 0) {
|
||||||
|
*warn = strdup(warnings.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" int msc_rules_add_file(RulesSet *rules, const char *file,
|
extern "C" int msc_rules_add_file(RulesSet *rules, const char *file,
|
||||||
const char **error) {
|
const char **warn, const char **error) {
|
||||||
int ret = rules->loadFromUri(file);
|
int ret = rules->loadFromUri(file);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
*error = strdup(rules->getParserError().c_str());
|
*error = strdup(rules->getParserError().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warnings = rules->getParserWarnings();
|
||||||
|
if (warnings.size() > 0) {
|
||||||
|
*warn = strdup(warnings.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" int msc_rules_add(RulesSet *rules, const char *plain_rules,
|
extern "C" int msc_rules_add(RulesSet *rules, const char *plain_rules,
|
||||||
const char **error) {
|
const char **warn, const char **error) {
|
||||||
int ret = rules->load(plain_rules);
|
int ret = rules->load(plain_rules);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
*error = strdup(rules->getParserError().c_str());
|
*error = strdup(rules->getParserError().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto warnings = rules->getParserWarnings();
|
||||||
|
if (warnings.size() > 0) {
|
||||||
|
*warn = strdup(warnings.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ modsecurity::ModSecurity *setupModSec() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
modsecurity::RulesSet *setupModSecRules(RegressionTestResult *r) {
|
modsecurity::RulesSet *setupModSecRules(RegressionTestResult *r, std::string &warning) {
|
||||||
CustomDebugLog *debug_log = new CustomDebugLog();
|
CustomDebugLog *debug_log = new CustomDebugLog();
|
||||||
auto rules = new modsecurity::RulesSet(debug_log);
|
auto rules = new modsecurity::RulesSet(debug_log);
|
||||||
rules->load("SecDebugLogLevel 9");
|
rules->load("SecDebugLogLevel 9");
|
||||||
@ -165,8 +165,11 @@ modsecurity::RulesSet *setupModSecRules(RegressionTestResult *r) {
|
|||||||
|
|
||||||
if (rules->load(r->getRules().c_str(), r->getFileName()) >= 0 &&
|
if (rules->load(r->getRules().c_str(), r->getFileName()) >= 0 &&
|
||||||
r->getExpectedParserError().empty()) {
|
r->getExpectedParserError().empty()) {
|
||||||
|
warning.assign(rules->getParserWarnings());
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
warning.assign(rules->getParserWarnings());
|
||||||
|
|
||||||
|
|
||||||
if (!r->getExpectedParserError().empty()) {
|
if (!r->getExpectedParserError().empty()) {
|
||||||
Regex re(r->getExpectedParserError());
|
Regex re(r->getExpectedParserError());
|
||||||
@ -287,6 +290,7 @@ void processLogs(RegressionTest *t,
|
|||||||
const std::string &serverLog,
|
const std::string &serverLog,
|
||||||
const std::string &audit_log,
|
const std::string &audit_log,
|
||||||
const std::string &debug_log,
|
const std::string &debug_log,
|
||||||
|
const std::string &parser_warning,
|
||||||
int status_code) {
|
int status_code) {
|
||||||
|
|
||||||
|
|
||||||
@ -318,6 +322,13 @@ void processLogs(RegressionTest *t,
|
|||||||
reason << KWHT << "Expecting: " << RESET \
|
reason << KWHT << "Expecting: " << RESET \
|
||||||
<< t->audit_log + "";
|
<< t->audit_log + "";
|
||||||
testRes->failed(reason.str());
|
testRes->failed(reason.str());
|
||||||
|
} else if (!contains(parser_warning, t->parser_warn)) {
|
||||||
|
std::stringstream reason;
|
||||||
|
reason << "Parser warning was not matching the " \
|
||||||
|
<< "expected results." << std::endl;
|
||||||
|
reason << KWHT << "Expecting: " << RESET \
|
||||||
|
<< t->parser_warn + "";
|
||||||
|
testRes->failed(reason.str());
|
||||||
} else {
|
} else {
|
||||||
testRes->passed();
|
testRes->passed();
|
||||||
return;
|
return;
|
||||||
@ -331,6 +342,8 @@ void processLogs(RegressionTest *t,
|
|||||||
testRes->reason << serverLog << std::endl;
|
testRes->reason << serverLog << std::endl;
|
||||||
testRes->reason << KWHT << "Audit log:" << RESET << std::endl;
|
testRes->reason << KWHT << "Audit log:" << RESET << std::endl;
|
||||||
testRes->reason << audit_log << std::endl;
|
testRes->reason << audit_log << std::endl;
|
||||||
|
testRes->reason << KWHT << "Parser warning:" << RESET << std::endl;
|
||||||
|
testRes->reason << parser_warning << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +359,7 @@ RegressionTestResult *perform_regression_test(
|
|||||||
std::string error_log;
|
std::string error_log;
|
||||||
std::string audit_log;
|
std::string audit_log;
|
||||||
std::string debug_log;
|
std::string debug_log;
|
||||||
|
std::string parser_warning;
|
||||||
int status_code = 200;
|
int status_code = 200;
|
||||||
|
|
||||||
if (t->enabled == 0) {
|
if (t->enabled == 0) {
|
||||||
@ -363,7 +377,7 @@ RegressionTestResult *perform_regression_test(
|
|||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
modsec_rules = setupModSecRules(testRes);
|
modsec_rules = setupModSecRules(testRes, parser_warning);
|
||||||
if (modsec_rules == nullptr) {
|
if (modsec_rules == nullptr) {
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
@ -381,6 +395,7 @@ RegressionTestResult *perform_regression_test(
|
|||||||
error_log,
|
error_log,
|
||||||
audit_log,
|
audit_log,
|
||||||
debug_log,
|
debug_log,
|
||||||
|
parser_warning,
|
||||||
status_code);
|
status_code);
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
|
@ -197,6 +197,9 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) {
|
|||||||
if (strcmp(key2, "parser_error") == 0) {
|
if (strcmp(key2, "parser_error") == 0) {
|
||||||
u->parser_error = YAJL_GET_STRING(val2);
|
u->parser_error = YAJL_GET_STRING(val2);
|
||||||
}
|
}
|
||||||
|
if (strcmp(key2, "parser_warn") == 0) {
|
||||||
|
u->parser_warn = YAJL_GET_STRING(val2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strcmp(key, "rules") == 0) {
|
if (strcmp(key, "rules") == 0) {
|
||||||
|
@ -58,6 +58,7 @@ class RegressionTest {
|
|||||||
std::string debug_log;
|
std::string debug_log;
|
||||||
std::string error_log;
|
std::string error_log;
|
||||||
std::string parser_error;
|
std::string parser_error;
|
||||||
|
std::string parser_warn;
|
||||||
|
|
||||||
std::string clientIp;
|
std::string clientIp;
|
||||||
std::string serverIp;
|
std::string serverIp;
|
||||||
|
63
test/test-cases/regression/config-warning.json
Normal file
63
test/test-cases/regression/config-warning.json
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing parser warning (1/n)",
|
||||||
|
"expected":{
|
||||||
|
"parser_warn": "Action ctl:forceRequestBodyVariable is not supported in version 3"
|
||||||
|
},
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":12300
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"a.b.com",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"User-Agent":"My sweet little browser",
|
||||||
|
"Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120"
|
||||||
|
},
|
||||||
|
"uri":"/path1",
|
||||||
|
"method":"GET"
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5,ctl:forceRequestBodyVariable=Off\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing parser warning (2/n)",
|
||||||
|
"expected":{
|
||||||
|
"parser_warn": "config-warning.json. Line: 2. Column: 58. Action ctl:forceRequestBodyVariable is not supported in version 3."
|
||||||
|
},
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":12300
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"a.b.com",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"User-Agent":"My sweet little browser",
|
||||||
|
"Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120"
|
||||||
|
},
|
||||||
|
"uri":"/path1",
|
||||||
|
"method":"GET"
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5,ctl:forceRequestBodyVariable=Off\"",
|
||||||
|
"SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:7,ctl:forceRequestBodyVariable=On\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user