From 0d53dda1a1055b5ee328ef501fcfa11be67a9872 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Tue, 21 Jun 2016 13:46:05 -0300 Subject: [PATCH] Adds support to @unconditionalMatch Issue #1002 --- Makefile.am | 1 + src/Makefile.am | 3 +- src/operators/operator.cc | 5 ++ src/operators/unconditional_match.cc | 33 +++++++++++++ src/operators/unconditional_match.h | 43 +++++++++++++++++ src/parser/seclang-scanner.ll | 2 +- .../operator-UnconditionalMatch.json | 48 +++++++++++++++++++ 7 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/operators/unconditional_match.cc create mode 100644 src/operators/unconditional_match.h create mode 100644 test/test-cases/regression/operator-UnconditionalMatch.json diff --git a/Makefile.am b/Makefile.am index 3d10bbc3..1378ef0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -221,3 +221,4 @@ TESTS+=test/test-cases/regression/variable-RULE.json TESTS+=test/test-cases/regression/variable-STATUS.json TESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json TESTS+=test/test-cases/regression/variable-SERVER_NAME.json +TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json diff --git a/src/Makefile.am b/src/Makefile.am index a33bd671..5989af04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -180,7 +180,8 @@ OPERATORS = \ operators/verify_cc.cc \ operators/verify_cpf.cc \ operators/verify_ssn.cc \ - operators/within.cc + operators/within.cc \ + operators/unconditional_match.cc UTILS = \ diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 2571407a..7918d725 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -58,6 +58,7 @@ #include "operators/verify_cpf.h" #include "operators/verify_ssn.h" #include "operators/within.h" +#include "operators/unconditional_match.h" #define IF_MATCH(a) \ if (op_ == #a) @@ -172,6 +173,10 @@ Operator *Operator::instantiate(std::string op_string) { IF_MATCH(verifyssn) { return new VerifySSN(op, param, negation); } IF_MATCH(within) { return new Within(op, param, negation); } + IF_MATCH(unconditionalmatch) { + return new UnconditionalMatch(op, param, negation); + } + return new Operator(op, param, negation); } diff --git a/src/operators/unconditional_match.cc b/src/operators/unconditional_match.cc new file mode 100644 index 00000000..faad3edc --- /dev/null +++ b/src/operators/unconditional_match.cc @@ -0,0 +1,33 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "operators/unconditional_match.h" + +namespace modsecurity { +namespace operators { + +bool UnconditionalMatch::evaluate(Transaction *transaction, + const std::string &input) { + bool contains = true; + + if (negation) { + return !contains; + } + + return contains; +} + +} // namespace operators +} // namespace modsecurity diff --git a/src/operators/unconditional_match.h b/src/operators/unconditional_match.h new file mode 100644 index 00000000..32ea78ab --- /dev/null +++ b/src/operators/unconditional_match.h @@ -0,0 +1,43 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#ifndef SRC_OPERATORS_UNCONDITIONAL_MATCH_H_ +#define SRC_OPERATORS_UNCONDITIONAL_MATCH_H_ + +#include +#include + +#include "modsecurity/transaction.h" +#include "operators/operator.h" + +#ifdef __cplusplus +namespace modsecurity { +namespace operators { + +class UnconditionalMatch : public Operator { + public: + /** @ingroup ModSecurity_Operator */ + UnconditionalMatch(std::string op, std::string param, bool negation) + : Operator(op, param, negation) { } + + bool evaluate(Transaction *transaction, const std::string &exp) override; +}; + +} // namespace operators +} // namespace modsecurity +#endif + + +#endif // SRC_OPERATORS_UNCONDITIONAL_MATCH_H_ diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index dccc03b7..824df24b 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -120,7 +120,7 @@ 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)) -OPERATORNOARG (?i:@detectSQLi|@detectXSS|@validateUrlEncoding|@validateUtf8Encoding) +OPERATORNOARG (?i:@unconditionalMatch|@detectSQLi|@detectXSS|@validateUrlEncoding|@validateUtf8Encoding) OPERATOR_GEOIP (?i:@geoLookup) TRANSFORMATION t:(?i:(parityZero7bit|parityOdd7bit|parityEven7bit|sqlHexDecode|cmdLine|sha1|md5|hexEncode|lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim|normalizePathWin|normalisePathWin|normalisePath|length|utf8toUnicode|urldecode|removeCommentsChar|removeComments|replaceComments)) diff --git a/test/test-cases/regression/operator-UnconditionalMatch.json b/test/test-cases/regression/operator-UnconditionalMatch.json new file mode 100644 index 00000000..3365089f --- /dev/null +++ b/test/test-cases/regression/operator-UnconditionalMatch.json @@ -0,0 +1,48 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing Operator :: @UnconditionalMatch", + "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":"*/*", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded" + }, + "uri":"/", + "method":"POST", + "body": [ + "param1=value1¶m2=value2" + ] + }, + "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":"Rule returned 1" + }, + "rules":[ + "SecRuleEngine On", + "SecDebugLog \/tmp\/modsec_debug.log", + "SecDebugLogLevel 9", + "SecRule ARGS \"@UnconditionalMatch\" \"id:1,phase:2,pass,t:trim\"" + ] + } +] \ No newline at end of file