From 15b81d09e7e6a5413a1148a39ba747f55cdb90b9 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Tue, 20 Dec 2016 14:56:28 -0300 Subject: [PATCH] Refactoring on the transformation classes --- src/actions/transformations/transformation.cc | 48 ---- src/actions/transformations/transformation.h | 5 - src/parser/seclang-parser.yy | 224 +++++++++++++++--- src/parser/seclang-scanner.ll | 180 +++++++++----- test/unit/unit.cc | 93 +++++++- 5 files changed, 406 insertions(+), 144 deletions(-) diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index eaa91902..309c10b0 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -58,10 +58,6 @@ #include "src/actions/transformations/url_encode.h" #include "src/actions/transformations/utf8_to_unicode.h" -#define IF_MATCH(b) \ - if (a.compare(2, std::strlen(#b), #b) == 0) - - namespace modsecurity { namespace actions { namespace transformations { @@ -73,50 +69,6 @@ std::string Transformation::evaluate(std::string value, } -Transformation* Transformation::instantiate(std::string a) { - IF_MATCH(base64DecodeExt) { return new Base64DecodeExt(a); } - IF_MATCH(base64Decode) { return new Base64Decode(a); } - IF_MATCH(base64Encode) { return new Base64Encode(a); } - IF_MATCH(cmd_line) { return new CmdLine(a); } - IF_MATCH(compress_whitespace) { return new CompressWhitespace(a); } - IF_MATCH(cssDecode) { return new CssDecode(a); } - IF_MATCH(escapeSeqDecode) { return new EscapeSeqDecode(a); } - IF_MATCH(hexDecode) { return new HexDecode(a); } - IF_MATCH(hexEncode) { return new HexEncode(a); } - IF_MATCH(htmlEntityDecode) { return new HtmlEntityDecode(a); } - IF_MATCH(jsDecode) { return new JsDecode(a); } - IF_MATCH(length) { return new Length(a); } - IF_MATCH(lowercase) { return new LowerCase(a); } - IF_MATCH(md5) { return new Md5(a); } - IF_MATCH(none) { return new None(a); } - IF_MATCH(normalizePathWin) { return new NormalisePathWin(a); } - IF_MATCH(normalisePathWin) { return new NormalisePathWin(a); } - IF_MATCH(normalizePath) { return new NormalisePath(a); } - IF_MATCH(normalisePath) { return new NormalisePath(a); } - IF_MATCH(parityEven7bit) { return new ParityEven7bit(a); } - IF_MATCH(parityOdd7bit) { return new ParityOdd7bit(a); } - IF_MATCH(parityZero7bit) { return new ParityZero7bit(a); } - IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); } - IF_MATCH(removeComments) { return new RemoveComments(a); } - IF_MATCH(removeNulls) { return new RemoveNulls(a); } - IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); } - IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); } - IF_MATCH(replaceComments) { return new ReplaceComments(a); } - IF_MATCH(replaceNulls) { return new ReplaceNulls(a); } - IF_MATCH(sha1) { return new Sha1(a); } - IF_MATCH(sqlHexDecode) { return new SqlHexDecode(a); } - IF_MATCH(transformation) { return new Transformation(a); } - IF_MATCH(trimLeft) { return new TrimLeft(a); } - IF_MATCH(trimRight) { return new TrimRight(a); } - IF_MATCH(trim) { return new Trim(a); } - IF_MATCH(urlDecodeUni) { return new UrlDecodeUni(a); } - IF_MATCH(urlDecode) { return new UrlDecode(a); } - IF_MATCH(urlEncode) { return new UrlEncode(a); } - IF_MATCH(utf8ToUnicode) { return new Utf8ToUnicode(a); } - - return new Transformation(a); -} - } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/transformation.h b/src/actions/transformations/transformation.h index 9d2990a0..2c0b6fa9 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -20,8 +20,6 @@ #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ -#ifdef __cplusplus - namespace modsecurity { class Transaction; @@ -36,8 +34,6 @@ class Transformation : public Action { explicit Transformation(const std::string& _action, int kind) : Action(_action, kind) { } - static Transformation* instantiate(std::string); - std::string evaluate(std::string exp, Transaction *transaction) override; }; @@ -46,6 +42,5 @@ class Transformation : public Action { } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index 52cd7a46..c2af1a9c 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -58,6 +58,43 @@ class Driver; #include "src/actions/ver.h" #include "src/actions/xmlns.h" +#include "src/actions/transformations/hex_encode.h" +#include "src/actions/transformations/parity_even_7bit.h" +#include "src/actions/transformations/utf8_to_unicode.h" +#include "src/actions/transformations/parity_zero_7bit.h" +#include "src/actions/transformations/sql_hex_decode.h" +#include "src/actions/transformations/replace_comments.h" +#include "src/actions/transformations/none.h" +#include "src/actions/transformations/url_decode.h" +#include "src/actions/transformations/lower_case.h" +#include "src/actions/transformations/hex_decode.h" +#include "src/actions/transformations/url_encode.h" +#include "src/actions/transformations/js_decode.h" +#include "src/actions/transformations/url_decode_uni.h" +#include "src/actions/transformations/parity_odd_7bit.h" +#include "src/actions/transformations/transformation.h" +#include "src/actions/transformations/trim_right.h" +#include "src/actions/transformations/escape_seq_decode.h" +#include "src/actions/transformations/base64_decode_ext.h" +#include "src/actions/transformations/base64_decode.h" +#include "src/actions/transformations/trim.h" +#include "src/actions/transformations/cmd_line.h" +#include "src/actions/transformations/replace_nulls.h" +#include "src/actions/transformations/md5.h" +#include "src/actions/transformations/length.h" +#include "src/actions/transformations/sha1.h" +#include "src/actions/transformations/compress_whitespace.h" +#include "src/actions/transformations/normalise_path_win.h" +#include "src/actions/transformations/remove_nulls.h" +#include "src/actions/transformations/remove_comments.h" +#include "src/actions/transformations/normalise_path.h" +#include "src/actions/transformations/html_entity_decode.h" +#include "src/actions/transformations/trim_left.h" +#include "src/actions/transformations/remove_comments_char.h" +#include "src/actions/transformations/base64_encode.h" +#include "src/actions/transformations/remove_whitespace.h" +#include "src/actions/transformations/css_decode.h" + #include "modsecurity/audit_log.h" @@ -238,6 +275,36 @@ using modsecurity::operators::Operator; %token ACTION_VER %token ACTION_XMLNS +%token ACTION_TRANSFORMATION_CMD_LINE +%token ACTION_TRANSFORMATION_COMPRESS_WHITESPACE +%token ACTION_TRANSFORMATION_CSS_DECODE +%token ACTION_TRANSFORMATION_HEX_ENCODE +%token ACTION_TRANSFORMATION_HTML_ENTITY_DECODE +%token ACTION_TRANSFORMATION_JS_DECODE +%token ACTION_TRANSFORMATION_LENGTH +%token ACTION_TRANSFORMATION_LOWERCASE +%token ACTION_TRANSFORMATION_MD5 +%token ACTION_TRANSFORMATION_NONE +%token ACTION_TRANSFORMATION_NORMALISE_PATH +%token ACTION_TRANSFORMATION_NORMALISE_PATH_WIN +%token ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT +%token ACTION_TRANSFORMATION_PARITY_ODD_7_BIT +%token ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT +%token ACTION_TRANSFORMATION_REMOVE_COMMENTS +%token ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR +%token ACTION_TRANSFORMATION_REMOVE_NULLS +%token ACTION_TRANSFORMATION_REMOVE_WHITESPACE +%token ACTION_TRANSFORMATION_REPLACE_COMMENTS +%token ACTION_TRANSFORMATION_REPLACE_NULLS +%token ACTION_TRANSFORMATION_SHA1 +%token ACTION_TRANSFORMATION_SQL_HEX_DECODE +%token ACTION_TRANSFORMATION_TRIM +%token ACTION_TRANSFORMATION_URL_DECODE +%token ACTION_TRANSFORMATION_URL_DECODE_UNI +%token ACTION_TRANSFORMATION_UTF8_TO_UNICODE + + + %token CONFIG_COMPONENT_SIG %token CONFIG_DIR_AUDIT_DIR %token CONFIG_DIR_AUDIT_DIR_MOD @@ -315,19 +382,18 @@ using modsecurity::operators::Operator; %token RUN_TIME_VAR_TIME_WDAY %token RUN_TIME_VAR_TIME_YEAR %token RUN_TIME_VAR_XML -%token TRANSFORMATION %token VARIABLE %token VARIABLE_COL %token VARIABLE_STATUS %token VARIABLE_TX - %type act -%type op -%type var %type *> actings %type *> actions + %type *> variables +%type op +%type var %printer { yyoutput << $$; } <*>; @@ -467,6 +533,24 @@ actings: } ; +actions: + actions COMMA act + { + std::vector *a = $1; + ACTION_INIT($3, @0) + a->push_back($3); + $$ = $1; + } + | act + { + std::vector *a = new std::vector; + ACTION_INIT($1, @0) + a->push_back($1); + $$ = a; + } + ; + + op: OPERATOR { @@ -1207,19 +1291,19 @@ act: } | ACTION_SETSID { - $$ = new actions::SetSID($1); + $$ = new modsecurity::actions::SetSID($1); } | ACTION_SETUID { - $$ = new actions::SetUID($1); + $$ = new modsecurity::actions::SetUID($1); } | ACTION_SETVAR { - $$ = new actions::SetVar($1); + $$ = new modsecurity::actions::SetVar($1); } | ACTION_SEVERITY { - $$ = new actions::Severity($1); + $$ = new modsecurity::actions::Severity($1); } | ACTION_SKIP { @@ -1231,41 +1315,127 @@ act: } | ACTION_STATUS { - $$ = new actions::data::Status($1); + $$ = new modsecurity::actions::data::Status($1); } | ACTION_TAG { - $$ = new actions::Tag($1); + $$ = new modsecurity::actions::Tag($1); } | ACTION_VER { - $$ = new actions::Ver($1); + $$ = new modsecurity::actions::Ver($1); } | ACTION_XMLNS { $$ = new modsecurity::actions::XmlNS($1); } - - | TRANSFORMATION + | ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT { - $$ = actions::transformations::Transformation::instantiate($1); + $$ = new modsecurity::actions::transformations::ParityZero7bit($1); } - ; - -actions: - actions COMMA act + | ACTION_TRANSFORMATION_PARITY_ODD_7_BIT { - std::vector *a = $1; - ACTION_INIT($3, @0) - a->push_back($3); - $$ = $1; + $$ = new modsecurity::actions::transformations::ParityOdd7bit($1); } - | act + | ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT { - std::vector *a = new std::vector; - ACTION_INIT($1, @0) - a->push_back($1); - $$ = a; + $$ = new modsecurity::actions::transformations::ParityEven7bit($1); + } + | ACTION_TRANSFORMATION_SQL_HEX_DECODE + { + $$ = new modsecurity::actions::transformations::SqlHexDecode($1); + } + | ACTION_TRANSFORMATION_CMD_LINE + { + $$ = new modsecurity::actions::transformations::CmdLine($1); + } + | ACTION_TRANSFORMATION_SHA1 + { + $$ = new modsecurity::actions::transformations::Sha1($1); + } + | ACTION_TRANSFORMATION_MD5 + { + $$ = new modsecurity::actions::transformations::Md5($1); + } + | ACTION_TRANSFORMATION_HEX_ENCODE + { + $$ = new modsecurity::actions::transformations::HexEncode($1); + } + | ACTION_TRANSFORMATION_LOWERCASE + { + $$ = new modsecurity::actions::transformations::LowerCase($1); + } + | ACTION_TRANSFORMATION_URL_DECODE_UNI + { + $$ = new modsecurity::actions::transformations::UrlDecodeUni($1); + } + | ACTION_TRANSFORMATION_URL_DECODE + { + $$ = new modsecurity::actions::transformations::UrlDecode($1); + } + | ACTION_TRANSFORMATION_NONE + { + $$ = new modsecurity::actions::transformations::None($1); + } + | ACTION_TRANSFORMATION_COMPRESS_WHITESPACE + { + $$ = new modsecurity::actions::transformations::CompressWhitespace($1); + } + | ACTION_TRANSFORMATION_REMOVE_WHITESPACE + { + $$ = new modsecurity::actions::transformations::RemoveWhitespace($1); + } + | ACTION_TRANSFORMATION_REPLACE_NULLS + { + $$ = new modsecurity::actions::transformations::ReplaceNulls($1); + } + | ACTION_TRANSFORMATION_REMOVE_NULLS + { + $$ = new modsecurity::actions::transformations::RemoveNulls($1); + } + | ACTION_TRANSFORMATION_HTML_ENTITY_DECODE + { + $$ = new modsecurity::actions::transformations::HtmlEntityDecode($1); + } + | ACTION_TRANSFORMATION_JS_DECODE + { + $$ = new modsecurity::actions::transformations::JsDecode($1); + } + | ACTION_TRANSFORMATION_CSS_DECODE + { + $$ = new modsecurity::actions::transformations::CssDecode($1); + } + | ACTION_TRANSFORMATION_TRIM + { + $$ = new modsecurity::actions::transformations::Trim($1); + } + | ACTION_TRANSFORMATION_NORMALISE_PATH_WIN + { + $$ = new modsecurity::actions::transformations::NormalisePathWin($1); + } + | ACTION_TRANSFORMATION_NORMALISE_PATH + { + $$ = new modsecurity::actions::transformations::NormalisePath($1); + } + | ACTION_TRANSFORMATION_LENGTH + { + $$ = new modsecurity::actions::transformations::Length($1); + } + | ACTION_TRANSFORMATION_UTF8_TO_UNICODE + { + $$ = new modsecurity::actions::transformations::Utf8ToUnicode($1); + } + | ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR + { + $$ = new modsecurity::actions::transformations::RemoveCommentsChar($1); + } + | ACTION_TRANSFORMATION_REMOVE_COMMENTS + { + $$ = new modsecurity::actions::transformations::RemoveComments($1); + } + | ACTION_TRANSFORMATION_REPLACE_COMMENTS + { + $$ = new modsecurity::actions::transformations::ReplaceComments($1); } ; diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index 441c7cc7..cb7d8dc2 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -25,62 +25,90 @@ typedef yy::seclang_parser p; %} %option noyywrap nounput batch debug noinput -ACTION_ACCURACY (?i:accuracy) -ACTION_ALLOW ((?i:allow:(?i:REQUEST|PHASE))|(?i:phase:'(?i:REQUEST|PHASE)')|(?i:allow)) -ACTION_APPEND (?i:append) -ACTION_AUDIT_LOG (?i:auditlog) -ACTION_BLOCK (?i:block) -ACTION_CAPTURE (?i:capture) -ACTION_CHAIN (?i:chain) -ACTION_CTL_AUDIT_ENGINE (?i:ctl:auditEngine) -ACTION_CTL_AUDIT_LOG_PARTS (?i:ctl:auditLogParts) -ACTION_CTL_BDY_JSON (?i:ctl:requestBodyProcessor=JSON) -ACTION_CTL_BDY_XML (?i:ctl:requestBodyProcessor=XML) -ACTION_CTL_FORCE_REQ_BODY_VAR (?i:ctl:forceRequestBodyVariable) -ACTION_CTL_REQUEST_BODY_ACCESS (?i:ctl:requestBodyAccess) -ACTION_CTL_RULE_ENGINE (?i:ctl:ruleEngine) -ACTION_CTL_RULE_REMOVE_BY_ID (?i:ctl:ruleRemoveById) -ACTION_CTL_RULE_REMOVE_TARGET_BY_ID (?i:ctl:ruleRemoveTargetById) -ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG (?i:ctl:ruleRemoveTargetByTag) -ACTION_DENY (?i:deny) -ACTION_DEPRECATE_VAR (?i:deprecatevar) -ACTION_DROP (?i:drop) -ACTION_EXEC (?i:exec) -ACTION_EXPIRE_VAR (?i:expirevar) -ACTION_ID (?i:id:[0-9]+|id:'[0-9]+') -ACTION_INITCOL (?i:initcol) -ACTION_LOG_DATA (?i:logdata) -ACTION_LOG (?i:log) -ACTION_MATURITY (?i:maturity) -ACTION_MSG (?i:msg) -ACTION_MULTI_MATCH (?i:multiMatch) -ACTION_NO_AUDIT_LOG (?i:noauditlog) -ACTION_NO_LOG (?i:nolog) -ACTION_PASS (?i:pass) -ACTION_PAUSE (?i:pause) -ACTION_PHASE ((?i:phase:(?i:REQUEST|RESPONSE|LOGGING|[0-9]+))|(?i:phase:'(?i:REQUEST|RESPONSE|LOGGING|[0-9]+)')) -ACTION_PREPEND (?i:prepend) -ACTION_PROXY (?i:proxy) -ACTION_REDIRECT (?i:redirect) -ACTION_REV (?i:rev) -ACTION_SANATISE_ARG (?i:sanitiseArg) -ACTION_SANATISE_MATCHED_BYTES (?i:sanitiseMatchedBytes) -ACTION_SANATISE_MATCHED (?i:sanitiseMatched) -ACTION_SANATISE_REQUEST_HEADER (?i:sanitiseRequestHeader) -ACTION_SANATISE_RESPONSE_HEADER (?i:sanitiseResponseHeader) -ACTION_SETENV (?i:setenv) -ACTION_SETRSC (?i:setrsc) -ACTION_SETSID (?i:setsid) -ACTION_SETUID (?i:setuid) -ACTION_SETVAR (?i:setvar) -ACTION_SEVERITY (?i:severity) -ACTION_SEVERITY_VALUE (?i:(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)|[0-9]+) -ACTION_SKIP_AFTER (?i:skipAfter) -ACTION_SKIP (?i:skip) -ACTION_STATUS (?i:status:[0-9]+) -ACTION_TAG (?i:tag) -ACTION_VER (?i:ver) -ACTION_XMLNS (?i:xmlns) +ACTION_ACCURACY (?i:accuracy) +ACTION_ALLOW ((?i:allow:(?i:REQUEST|PHASE))|(?i:phase:'(?i:REQUEST|PHASE)')|(?i:allow)) +ACTION_APPEND (?i:append) +ACTION_AUDIT_LOG (?i:auditlog) +ACTION_BLOCK (?i:block) +ACTION_CAPTURE (?i:capture) +ACTION_CHAIN (?i:chain) +ACTION_CTL_AUDIT_ENGINE (?i:ctl:auditEngine) +ACTION_CTL_AUDIT_LOG_PARTS (?i:ctl:auditLogParts) +ACTION_CTL_BDY_JSON (?i:ctl:requestBodyProcessor=JSON) +ACTION_CTL_BDY_XML (?i:ctl:requestBodyProcessor=XML) +ACTION_CTL_FORCE_REQ_BODY_VAR (?i:ctl:forceRequestBodyVariable) +ACTION_CTL_REQUEST_BODY_ACCESS (?i:ctl:requestBodyAccess) +ACTION_CTL_RULE_ENGINE (?i:ctl:ruleEngine) +ACTION_CTL_RULE_REMOVE_BY_ID (?i:ctl:ruleRemoveById) +ACTION_CTL_RULE_REMOVE_TARGET_BY_ID (?i:ctl:ruleRemoveTargetById) +ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG (?i:ctl:ruleRemoveTargetByTag) +ACTION_DENY (?i:deny) +ACTION_DEPRECATE_VAR (?i:deprecatevar) +ACTION_DROP (?i:drop) +ACTION_EXEC (?i:exec) +ACTION_EXPIRE_VAR (?i:expirevar) +ACTION_ID (?i:id:[0-9]+|id:'[0-9]+') +ACTION_INITCOL (?i:initcol) +ACTION_LOG_DATA (?i:logdata) +ACTION_LOG (?i:log) +ACTION_MATURITY (?i:maturity) +ACTION_MSG (?i:msg) +ACTION_MULTI_MATCH (?i:multiMatch) +ACTION_NO_AUDIT_LOG (?i:noauditlog) +ACTION_NO_LOG (?i:nolog) +ACTION_PASS (?i:pass) +ACTION_PAUSE (?i:pause) +ACTION_PHASE ((?i:phase:(?i:REQUEST|RESPONSE|LOGGING|[0-9]+))|(?i:phase:'(?i:REQUEST|RESPONSE|LOGGING|[0-9]+)')) +ACTION_PREPEND (?i:prepend) +ACTION_PROXY (?i:proxy) +ACTION_REDIRECT (?i:redirect) +ACTION_REV (?i:rev) +ACTION_SANATISE_ARG (?i:sanitiseArg) +ACTION_SANATISE_MATCHED_BYTES (?i:sanitiseMatchedBytes) +ACTION_SANATISE_MATCHED (?i:sanitiseMatched) +ACTION_SANATISE_REQUEST_HEADER (?i:sanitiseRequestHeader) +ACTION_SANATISE_RESPONSE_HEADER (?i:sanitiseResponseHeader) +ACTION_SETENV (?i:setenv) +ACTION_SETRSC (?i:setrsc) +ACTION_SETSID (?i:setsid) +ACTION_SETUID (?i:setuid) +ACTION_SETVAR (?i:setvar) +ACTION_SEVERITY (?i:severity) +ACTION_SEVERITY_VALUE (?i:(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)|[0-9]+) +ACTION_SKIP_AFTER (?i:skipAfter) +ACTION_SKIP (?i:skip) +ACTION_STATUS (?i:status:[0-9]+) +ACTION_TAG (?i:tag) +ACTION_VER (?i:ver) +ACTION_XMLNS (?i:xmlns) + +ACTION_TRANSFORMATION_CMD_LINE (?i:t:cmdLine) +ACTION_TRANSFORMATION_COMPRESS_WHITESPACE (?i:t:compressWhitespace) +ACTION_TRANSFORMATION_CSS_DECODE (?i:t:cssDecode) +ACTION_TRANSFORMATION_HEX_ENCODE (?i:t:hexEncode) +ACTION_TRANSFORMATION_HTML_ENTITY_DECODE (?i:t:htmlEntityDecode) +ACTION_TRANSFORMATION_JS_DECODE (?i:t:jsDecode) +ACTION_TRANSFORMATION_LENGTH (?i:t:length) +ACTION_TRANSFORMATION_LOWERCASE (?i:t:lowercase) +ACTION_TRANSFORMATION_MD5 (?i:t:md5) +ACTION_TRANSFORMATION_NONE (?i:t:none) +ACTION_TRANSFORMATION_NORMALISE_PATH (?i:t:(normalisePath|normalizePath)) +ACTION_TRANSFORMATION_NORMALISE_PATH_WIN (?i:t:(normalisePathWin|normalizePathWin)) +ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT (?i:t:parityEven7bit) +ACTION_TRANSFORMATION_PARITY_ODD_7_BIT (?i:t:parityOdd7bit) +ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT (?i:t:parityZero7bit) +ACTION_TRANSFORMATION_REMOVE_COMMENTS (?i:t:removeComments) +ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR (?i:t:removeCommentsChar) +ACTION_TRANSFORMATION_REMOVE_NULLS (?i:t:removeNulls) +ACTION_TRANSFORMATION_REMOVE_WHITESPACE (?i:t:removeWhitespace) +ACTION_TRANSFORMATION_REPLACE_COMMENTS (?i:t:replaceComments) +ACTION_TRANSFORMATION_REPLACE_NULLS (?i:t:replaceNulls) +ACTION_TRANSFORMATION_SHA1 (?i:t:sha1) +ACTION_TRANSFORMATION_SQL_HEX_DECODE (?i:t:sqlHexDecode) +ACTION_TRANSFORMATION_TRIM (?i:t:trim) +ACTION_TRANSFORMATION_URL_DECODE (?i:t:urlDecode) +ACTION_TRANSFORMATION_URL_DECODE_UNI (?i:t:urlDecodeUni) +ACTION_TRANSFORMATION_UTF8_TO_UNICODE (?i:t:utf8toUnicode) AUDIT_PARTS [ABCDEFHJKIZ]+ @@ -176,7 +204,6 @@ RUN_TIME_VAR_TIME_WDAY (?i:TIME_WDAY) RUN_TIME_VAR_TIME_YEAR (?i:TIME_YEAR) RUN_TIME_VAR_XML (?i:XML) SOMETHING ["]{1}([^"]|([^\\"]\\\"))*["]{1} -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|normalizePath|normalisePath|length|utf8toUnicode|urldecode|removeCommentsChar|removeComments|replaceComments)) VARIABLENOCOLON (?i:URLENCODED_ERROR|REQBODY_PROCESSOR_ERROR_MSG|REQBODY_PROCESSOR_ERROR|REQBODY_PROCESSOR|REQBODY_ERROR_MSG|REQBODY_ERROR|MULTIPART_FILE_LIMIT_EXCEEDED|MULTIPART_INVALID_QUOTING|MULTIPART_HEADER_FOLDING|MULTIPART_INVALID_HEADER_FOLDING|MULTIPART_STRICT_ERROR|MULTIPART_UNMATCHED_BOUNDARY|REMOTE_ADDR|REQUEST_LINE) VARIABLE (?i:(SERVER_NAME|MULTIPART_DATA_AFTER|RESOURCE|ARGS_COMBINED_SIZE|ARGS_GET_NAMES|ARGS_POST_NAMES|FILES_TMPNAMES|FILES_COMBINED_SIZE|FULL_REQUEST_LENGTH|REQUEST_BODY_LENGTH|REQUEST_URI_RAW|UNIQUE_ID|SERVER_PORT|SERVER_ADDR|REMOTE_PORT|REMOTE_HOST|PATH_INFO|MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VAR|INBOUND_DATA_ERROR|OUTBOUND_DATA_ERROR|FULL_REQUEST|AUTH_TYPE|ARGS_NAMES|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_PROTOCOL|RESPONSE_STATUS|USERID|SESSIONID)) VARIABLE_COL (?i:(SESSION|GLOBAL|ARGS_POST|ARGS_GET|ARGS|FILES_SIZES|FILES_NAMES|FILES_TMP_CONTENT|MULTIPART_FILENAME|MULTIPART_NAME|MATCHED_VARS_NAMES|MATCHED_VARS|FILES|QUERY_STRING|REQUEST_COOKIES|REQUEST_HEADERS|RESPONSE_HEADERS|GEO|IP|REQUEST_COOKIES_NAMES)) @@ -243,10 +270,10 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG}[=]{REMOVE_RULE_BY} { return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); } {ACTION_EXEC}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } {ACTION_EXEC}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}={VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } -{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE}={VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}={VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +{ACTION_EXPIRE_VAR}:'{VAR_FREE_TEXT_QUOTE}' { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } +{ACTION_EXPIRE_VAR}:{VAR_FREE_TEXT_SPACE}={VAR_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); } {ACTION_INITCOL}:{COL_NAME}={COL_FREE_TEXT_SPACE_COMMA} { return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); } {ACTION_MATURITY}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } {ACTION_MATURITY}:{FREE_TEXT_QUOTE} { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); } @@ -274,6 +301,36 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {ACTION_TAG}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_TAG(yytext, *driver.loc.back()); } {ACTION_VER}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_VER(yytext, *driver.loc.back()); } {ACTION_XMLNS}:{FREE_TEXT_SPACE_COMMA_QUOTE} { return p::make_ACTION_XMLNS(yytext, *driver.loc.back()); } + +{ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT} { return p::make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_PARITY_ODD_7_BIT} { return p::make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT} { return p::make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_SQL_HEX_DECODE} { return p::make_ACTION_TRANSFORMATION_SQL_HEX_DECODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_CMD_LINE} { return p::make_ACTION_TRANSFORMATION_CMD_LINE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_SHA1} { return p::make_ACTION_TRANSFORMATION_SHA1(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_MD5} { return p::make_ACTION_TRANSFORMATION_MD5(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_HEX_ENCODE} { return p::make_ACTION_TRANSFORMATION_HEX_ENCODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_LOWERCASE} { return p::make_ACTION_TRANSFORMATION_LOWERCASE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_URL_DECODE_UNI} { return p::make_ACTION_TRANSFORMATION_URL_DECODE_UNI(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_URL_DECODE} { return p::make_ACTION_TRANSFORMATION_URL_DECODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_NONE} { return p::make_ACTION_TRANSFORMATION_NONE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_COMPRESS_WHITESPACE} { return p::make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REMOVE_WHITESPACE} { return p::make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REPLACE_NULLS} { return p::make_ACTION_TRANSFORMATION_REPLACE_NULLS(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REMOVE_NULLS} { return p::make_ACTION_TRANSFORMATION_REMOVE_NULLS(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_HTML_ENTITY_DECODE} { return p::make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_JS_DECODE} { return p::make_ACTION_TRANSFORMATION_JS_DECODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_CSS_DECODE} { return p::make_ACTION_TRANSFORMATION_CSS_DECODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_TRIM} { return p::make_ACTION_TRANSFORMATION_TRIM(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_NORMALISE_PATH_WIN} { return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_NORMALISE_PATH} { return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_LENGTH} { return p::make_ACTION_TRANSFORMATION_LENGTH(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_UTF8_TO_UNICODE} { return p::make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR} { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REMOVE_COMMENTS} { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); } +{ACTION_TRANSFORMATION_REPLACE_COMMENTS} { return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); } + + {ACTION_LOG_DATA}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); } {CONFIG_COMPONENT_SIG}[ \t]+["]{FREE_TEXT}["] { return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } {CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); } @@ -330,7 +387,6 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {CONGIG_DIR_SEC_TMP_DIR}[ ]{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_TMP_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); } {DIRECTIVE_SECRULESCRIPT}[ ]{CONFIG_VALUE_PATH} { return p::make_DIRECTIVE_SECRULESCRIPT(yytext, *driver.loc.back()); } {DIRECTIVE} { return p::make_DIRECTIVE(yytext, *driver.loc.back()); } -{TRANSFORMATION} { return p::make_TRANSFORMATION(yytext, *driver.loc.back()); } {CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); } {CONFIG_SEC_COLLECTION_TIMEOUT}[ ]{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); } [ \t]*[\n] { driver.loc.back()->lines(1); driver.loc.back()->step(); } diff --git a/test/unit/unit.cc b/test/unit/unit.cc index 2ff5592a..9ae70cd1 100644 --- a/test/unit/unit.cc +++ b/test/unit/unit.cc @@ -14,15 +14,55 @@ */ #include +#include -#include #include +#include #include + #include "modsecurity/modsecurity.h" #include "modsecurity/rules.h" #include "src/operators/operator.h" #include "src/actions/transformations/transformation.h" +#include "modsecurity/transaction.h" +#include "modsecurity/actions/action.h" +#include "src/actions/transformations/base64_decode_ext.h" +#include "src/actions/transformations/base64_decode.h" +#include "src/actions/transformations/base64_encode.h" +#include "src/actions/transformations/cmd_line.h" +#include "src/actions/transformations/compress_whitespace.h" +#include "src/actions/transformations/css_decode.h" +#include "src/actions/transformations/escape_seq_decode.h" +#include "src/actions/transformations/hex_decode.h" +#include "src/actions/transformations/hex_encode.h" +#include "src/actions/transformations/html_entity_decode.h" +#include "src/actions/transformations/js_decode.h" +#include "src/actions/transformations/length.h" +#include "src/actions/transformations/lower_case.h" +#include "src/actions/transformations/md5.h" +#include "src/actions/transformations/none.h" +#include "src/actions/transformations/normalise_path.h" +#include "src/actions/transformations/normalise_path_win.h" +#include "src/actions/transformations/parity_even_7bit.h" +#include "src/actions/transformations/parity_odd_7bit.h" +#include "src/actions/transformations/parity_zero_7bit.h" +#include "src/actions/transformations/remove_comments_char.h" +#include "src/actions/transformations/remove_comments.h" +#include "src/actions/transformations/remove_nulls.h" +#include "src/actions/transformations/remove_whitespace.h" +#include "src/actions/transformations/replace_comments.h" +#include "src/actions/transformations/replace_nulls.h" +#include "src/actions/transformations/sha1.h" +#include "src/actions/transformations/sql_hex_decode.h" +#include "src/actions/transformations/trim.h" +#include "src/actions/transformations/trim_left.h" +#include "src/actions/transformations/trim_right.h" +#include "src/actions/transformations/url_decode.h" +#include "src/actions/transformations/url_decode_uni.h" +#include "src/actions/transformations/url_encode.h" +#include "src/actions/transformations/utf8_to_unicode.h" + #include "test/common/modsecurity_test.h" #include "test/common/modsecurity_test_results.h" @@ -30,12 +70,16 @@ #include "test/unit/unit_test.h" #include "src/utils/string.h" +#define IF_MATCH(b) \ + if (a.compare(2, std::strlen(#b), #b) == 0) + using modsecurity_test::UnitTest; using modsecurity_test::ModSecurityTest; using modsecurity_test::ModSecurityTestResults; using modsecurity::actions::transformations::Transformation; using modsecurity::operators::Operator; +using namespace modsecurity::actions::transformations; std::string default_test_path = "test-cases/secrules-language-tests/operators"; @@ -46,6 +90,51 @@ void print_help() { } +Transformation* t_instantiate(std::string a) { + IF_MATCH(base64DecodeExt) { return new Base64DecodeExt(a); } + IF_MATCH(base64Decode) { return new Base64Decode(a); } + IF_MATCH(base64Encode) { return new Base64Encode(a); } + IF_MATCH(cmd_line) { return new CmdLine(a); } + IF_MATCH(compress_whitespace) { return new CompressWhitespace(a); } + IF_MATCH(cssDecode) { return new CssDecode(a); } + IF_MATCH(escapeSeqDecode) { return new EscapeSeqDecode(a); } + IF_MATCH(hexDecode) { return new HexDecode(a); } + IF_MATCH(hexEncode) { return new HexEncode(a); } + IF_MATCH(htmlEntityDecode) { return new HtmlEntityDecode(a); } + IF_MATCH(jsDecode) { return new JsDecode(a); } + IF_MATCH(length) { return new Length(a); } + IF_MATCH(lowercase) { return new LowerCase(a); } + IF_MATCH(md5) { return new Md5(a); } + IF_MATCH(none) { return new None(a); } + IF_MATCH(normalizePathWin) { return new NormalisePathWin(a); } + IF_MATCH(normalisePathWin) { return new NormalisePathWin(a); } + IF_MATCH(normalizePath) { return new NormalisePath(a); } + IF_MATCH(normalisePath) { return new NormalisePath(a); } + IF_MATCH(parityEven7bit) { return new ParityEven7bit(a); } + IF_MATCH(parityOdd7bit) { return new ParityOdd7bit(a); } + IF_MATCH(parityZero7bit) { return new ParityZero7bit(a); } + IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); } + IF_MATCH(removeComments) { return new RemoveComments(a); } + IF_MATCH(removeNulls) { return new RemoveNulls(a); } + IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); } + IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); } + IF_MATCH(replaceComments) { return new ReplaceComments(a); } + IF_MATCH(replaceNulls) { return new ReplaceNulls(a); } + IF_MATCH(sha1) { return new Sha1(a); } + IF_MATCH(sqlHexDecode) { return new SqlHexDecode(a); } + IF_MATCH(transformation) { return new Transformation(a); } + IF_MATCH(trimLeft) { return new TrimLeft(a); } + IF_MATCH(trimRight) { return new TrimRight(a); } + IF_MATCH(trim) { return new Trim(a); } + IF_MATCH(urlDecodeUni) { return new UrlDecodeUni(a); } + IF_MATCH(urlDecode) { return new UrlDecode(a); } + IF_MATCH(urlEncode) { return new UrlEncode(a); } + IF_MATCH(utf8ToUnicode) { return new Utf8ToUnicode(a); } + + return new Transformation(a); +} + + void perform_unit_test(ModSecurityTest *test, UnitTest *t, ModSecurityTestResults* res) { std::string error; @@ -70,7 +159,7 @@ void perform_unit_test(ModSecurityTest *test, UnitTest *t, } delete op; } else if (t->type == "tfn") { - Transformation *tfn = Transformation::instantiate("t:" + t->name); + Transformation *tfn = t_instantiate("t:" + t->name); std::string ret = tfn->evaluate(t->input, NULL); t->obtained = 1; t->obtainedOutput = ret;