From 21f4c49a0fcd3dcb67f574b7354f9faf7f1fc77c Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Tue, 21 Jul 2015 14:32:05 -0300 Subject: [PATCH] Adds support to MATCHED_VAR_NAME variable --- src/parser/seclang-scanner.ll | 2 +- src/rule.cc | 5 ++ .../regression/variable-MATCHED_VAR_NAME.json | 90 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 test/test-cases/regression/variable-MATCHED_VAR_NAME.json diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index 9de669e2..203f0df6 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -59,7 +59,7 @@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@valida TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim) -VARIABLE (?i:MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO) +VARIABLE (?i:MATCHED_VAR_NAME|MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO) RUN_TIME_VAR_DUR (?i:DURATION) RUN_TIME_VAR_ENV (?i:ENV) RUN_TIME_VAR_BLD (?i:MODSEC_BUILD) diff --git a/src/rule.cc b/src/rule.cc index e720503f..1301e312 100644 --- a/src/rule.cc +++ b/src/rule.cc @@ -122,6 +122,10 @@ bool Rule::evaluate(Assay *assay) { value) == false) { assay->store_variable("MATCHED_VAR", value); } + if (assay->update_variable_first("MATCHED_VAR_NAME", + v.first) == false) { + assay->store_variable("MATCHED_VAR_NAME", v.first); + } assay->store_variable("MATCHED_VARS:" + v.first, value); assay->store_variable("MATCHED_VARS_NAMES:" + v.first, v.first); @@ -129,6 +133,7 @@ bool Rule::evaluate(Assay *assay) { assay->update_variable_first("MATCHED_VAR", ""); assay->delete_variable("MATCHED_VARS:" + v.first); assay->delete_variable("MATCHED_VARS_NAMES:" + v.first); + assay->delete_variable("MATCHED_VARS_NAMES:" + v.first); } } else { assay->debug(4, "Rule returned 0."); diff --git a/test/test-cases/regression/variable-MATCHED_VAR_NAME.json b/test/test-cases/regression/variable-MATCHED_VAR_NAME.json new file mode 100644 index 00000000..db77aa16 --- /dev/null +++ b/test/test-cases/regression/variable-MATCHED_VAR_NAME.json @@ -0,0 +1,90 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: MATCHED_VAR_NAME (1/2)", + "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":"*/*" + }, + "uri":"/?keyI=value&keyII=other_value", + "protocol":"GET" + }, + "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: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS:keyI \"@contains value\" \"chain,id:28\"", + "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", + "SecRule MATCHED_VAR_NAME \"@contains asdf\" \"pass\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: MATCHED_VAR_NAME (2/2)", + "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":"*/*" + }, + "uri":"/?keyI=value&keyII=other_value", + "protocol":"GET" + }, + "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: \"ARGS:keyII\" \\(Variable: MATCHED_VAR_NAME\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS:keyI \"@contains value\" \"chain,id:28\"", + "SecRule ARGS:keyII \"@contains other_value\" \"chain\"", + "SecRule MATCHED_VAR_NAME \"@contains asdf\" \"pass\"", + "SecRule MATCHED_VAR_NAME \"@contains value\" \"id:29\"" + ] + } +] +