diff --git a/headers/modsecurity/rules.h b/headers/modsecurity/rules.h index c5e4a647..524db232 100644 --- a/headers/modsecurity/rules.h +++ b/headers/modsecurity/rules.h @@ -18,6 +18,7 @@ #include #include #include +#include #endif @@ -121,6 +122,7 @@ class Rules { int debug_level; DebugLog *debug_log; void debug(int level, std::string message); + std::list components; AuditLog *audit_log; diff --git a/src/parser/driver.h b/src/parser/driver.h index 0e1e1a1f..d3778450 100644 --- a/src/parser/driver.h +++ b/src/parser/driver.h @@ -18,6 +18,7 @@ #include #include #include +#include #endif #ifndef SRC_PARSER_DRIVER_H_ @@ -88,6 +89,7 @@ class Driver { bool sec_response_body_access; std::string debug_log_path; + std::list components; ModSecurity::AuditLog *audit_log; diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index 575b3f4a..ecad1b4b 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -74,6 +74,8 @@ using ModSecurity::Rule; %token CONFIG_DIR_AUDIT_STS %token CONFIG_DIR_AUDIT_TPE +%token CONFIG_COMPONENT_SIG + %token CONFIG_DIR_DEBUG_LOG %token CONFIG_DIR_DEBUG_LVL @@ -212,6 +214,10 @@ expression: { driver.sec_request_body_access = false; } + | CONFIG_COMPONENT_SIG + { + driver.components.push_back($1); + } /* Debug log: start */ | CONFIG_DIR_DEBUG_LVL { diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index 6c1ad6e0..d68bef97 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -43,6 +43,7 @@ CONFIG_DIR_AUDIT_TPE (?i:SecAuditLogType) CONFIG_DIR_DEBUG_LOG SecDebugLog CONFIG_DIR_DEBUG_LVL SecDebugLogLevel +CONFIG_COMPONENT_SIG (?i:SecComponentSignature) CONFIG_INCLUDE Include DICT_ELEMENT [A-Za-z_]+ @@ -105,6 +106,7 @@ FREE_TEXT [^\"]+ {CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, loc); } {CONFIG_DIR_DEBUG_LVL}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, loc); } +{CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, loc); } {CONFIG_VALUE_ON} { return yy::seclang_parser::make_CONFIG_VALUE_ON(yytext, loc); } {CONFIG_VALUE_OFF} { return yy::seclang_parser::make_CONFIG_VALUE_OFF(yytext, loc); } diff --git a/src/rules.cc b/src/rules.cc index d6df4ea0..0b3b6584 100644 --- a/src/rules.cc +++ b/src/rules.cc @@ -161,6 +161,7 @@ int Rules::merge(Driver *from) { this->sec_response_body_access = from->sec_response_body_access; this->debug_log_path = from->debug_log_path; this->debug_level = from->debug_level; + this->components = from->components; if (m_custom_debug_log) { this->debug_log = m_custom_debug_log->new_instance(); @@ -194,6 +195,7 @@ int Rules::merge(Rules *from) { this->sec_audit_engine = from->sec_audit_engine; this->sec_request_body_access = from->sec_request_body_access; this->sec_response_body_access = from->sec_response_body_access; + this->components = from->components; this->debug_log = from->debug_log; diff --git a/test/test-cases/regression/sec_component_signature.json b/test/test-cases/regression/sec_component_signature.json new file mode 100644 index 00000000..86d61b8f --- /dev/null +++ b/test/test-cases/regression/sec_component_signature.json @@ -0,0 +1,55 @@ +[ + { + "enabled":1, + "version_min":300000, + "version_max":0, + "title":"SecComponentSignature", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1= test ¶m2=test2", + "protocol": "GET", + "http_version": 1.1, + "body": "" + }, + "response": { + "headers": { + "Content-Type": "plain\/text\n\r" + }, + "body": [ + "test" + ] + }, + "expected":{ + "audit_log":"", + "debug_log":".*", + "error_log":"", + "http_code": 403 + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecComponentSignature \"OWASP_CRS/2.2.9\"", + "SecRule ARGS \"@contains test\" \"t:trim,block,auditlog\"" + ] + } +] \ No newline at end of file