From 5e59d1912112ddfba108ebb4c1c5efc6f7838967 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Wed, 8 Mar 2017 17:49:12 -0300 Subject: [PATCH] Improves macro expansion speed and variable set attribution --- src/anchored_set_variable.cc | 4 +- src/macro_expansion.cc | 145 +++++++++++++++++------------------ src/macro_expansion.h | 8 ++ 3 files changed, 83 insertions(+), 74 deletions(-) diff --git a/src/anchored_set_variable.cc b/src/anchored_set_variable.cc index fe364686..0ea36874 100644 --- a/src/anchored_set_variable.cc +++ b/src/anchored_set_variable.cc @@ -30,7 +30,9 @@ namespace modsecurity { AnchoredSetVariable::AnchoredSetVariable(Transaction *t, std::string name) : m_transaction(t), - m_name(name) { } + m_name(name) { + reserve(10); + } AnchoredSetVariable::~AnchoredSetVariable() { diff --git a/src/macro_expansion.cc b/src/macro_expansion.cc index 9ac1d4db..cb51807c 100644 --- a/src/macro_expansion.cc +++ b/src/macro_expansion.cc @@ -71,168 +71,167 @@ std::string MacroExpansion::expand(const std::string& input, if (collection == std::string::npos) { collection = variable.find(":"); } - variable = utils::string::toupper(variable); if (collection == std::string::npos) { - if (variable == "ARGS_NAMES") { + if (compareStrNoCase(variable, "ARGS_NAMES")) { variableValue = transaction->m_variableArgsNames.resolveFirst(); } - else if (variable == "ARGS_GET_NAMES") { + else if (compareStrNoCase(variable, "ARGS_GET_NAMES")) { variableValue = transaction->m_variableArgGetNames.resolveFirst(); } - else if (variable == "ARGS_POST_NAMES") { + else if (compareStrNoCase(variable, "ARGS_POST_NAMES")) { variableValue = transaction->m_variableArgPostNames.resolveFirst(); } - else if (variable == "REQUEST_HEADERS_NAMES") { + else if (compareStrNoCase(variable, "REQUEST_HEADERS_NAMES")) { variableValue = transaction->m_variableRequestHeadersNames.resolveFirst(); } - else if (variable == "RESPONSE_CONTENT_TYPE") { + else if (compareStrNoCase(variable, "RESPONSE_CONTENT_TYPE")) { variableValue = transaction->m_variableResponseContentType.resolveFirst(); } - else if (variable == "RESPONSE_HEADERS_NAMES") { + else if (compareStrNoCase(variable, "RESPONSE_HEADERS_NAMES")) { variableValue = transaction->m_variableResponseHeadersNames.resolveFirst(); } - else if (variable == "ARGS_COMBINED_SIZE") { + else if (compareStrNoCase(variable, "ARGS_COMBINED_SIZE")) { variableValue = transaction->m_variableARGScombinedSize.resolveFirst(); } - else if (variable == "AUTH_TYPE") { + else if (compareStrNoCase(variable, "AUTH_TYPE")) { variableValue = transaction->m_variableAuthType.resolveFirst(); } - else if (variable == "FILES_COMBINED_SIZE") { + else if (compareStrNoCase(variable, "FILES_COMBINED_SIZE")) { variableValue = transaction->m_variableFilesCombinedSize.resolveFirst(); } - else if (variable == "FULL_REQUEST") { + else if (compareStrNoCase(variable, "FULL_REQUEST")) { variableValue = transaction->m_variableFullRequest.resolveFirst(); } - else if (variable == "FULL_REQUEST_LENGTH") { + else if (compareStrNoCase(variable, "FULL_REQUEST_LENGTH")) { variableValue = transaction->m_variableFullRequestLength.resolveFirst(); } - else if (variable == "INBOUND_DATA_ERROR") { + else if (compareStrNoCase(variable, "INBOUND_DATA_ERROR")) { variableValue = transaction->m_variableInboundDataError.resolveFirst(); } - else if (variable == "MATCHED_VAR") { + else if (compareStrNoCase(variable, "MATCHED_VAR")) { variableValue = transaction->m_variableMatchedVar.resolveFirst(); } - else if (variable == "MATCHED_VAR_NAME") { + else if (compareStrNoCase(variable, "MATCHED_VAR_NAME")) { variableValue = transaction->m_variableMatchedVarName.resolveFirst(); } - else if (variable == "MULTIPART_CRLF_LF_LINES") { + else if (compareStrNoCase(variable, "MULTIPART_CRLF_LF_LINES")) { variableValue = transaction->m_variableMultipartCrlfLFLines.resolveFirst(); } - else if (variable == "MULTIPART_DATA_AFTER") { + else if (compareStrNoCase(variable, "MULTIPART_DATA_AFTER")) { variableValue = transaction->m_variableMultipartDataAfter.resolveFirst(); } - else if (variable == "MULTIPART_FILE_LIMIT_EXCEEDED") { + else if (compareStrNoCase(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) { variableValue = transaction->m_variableMultipartFileLimitExceeded.resolveFirst(); } - else if (variable == "MULTIPART_STRICT_ERROR") { + else if (compareStrNoCase(variable, "MULTIPART_STRICT_ERROR")) { variableValue = transaction->m_variableMultipartStrictError.resolveFirst(); } - else if (variable == "MULTIPART_HEADER_FOLDING") { + else if (compareStrNoCase(variable, "MULTIPART_HEADER_FOLDING")) { variableValue = transaction->m_variableMultipartHeaderFolding.resolveFirst(); } - else if (variable == "MULTIPART_INVALID_QUOTING") { + else if (compareStrNoCase(variable, "MULTIPART_INVALID_QUOTING")) { variableValue = transaction->m_variableMultipartInvalidQuoting.resolveFirst(); } - else if (variable == "MULTIPART_INVALID_HEADER_FOLDING") { + else if (compareStrNoCase(variable, "MULTIPART_INVALID_HEADER_FOLDING")) { variableValue = transaction->m_variableMultipartInvalidHeaderFolding.resolveFirst(); } - else if (variable == "MULTIPART_UNMATCHED_BOUNDARY") { + else if (compareStrNoCase(variable, "MULTIPART_UNMATCHED_BOUNDARY")) { variableValue = transaction->m_variableMultipartUnmatchedBoundary.resolveFirst(); } - else if (variable == "OUTBOUND_DATA_ERROR") { + else if (compareStrNoCase(variable, "OUTBOUND_DATA_ERROR")) { variableValue = transaction->m_variableOutboundDataError.resolveFirst(); } - else if (variable == "PATH_INFO") { + else if (compareStrNoCase(variable, "PATH_INFO")) { variableValue = transaction->m_variablePathInfo.resolveFirst(); } - else if (variable == "QUERY_STRING") { + else if (compareStrNoCase(variable, "QUERY_STRING")) { variableValue = transaction->m_variableQueryString.resolveFirst(); } - else if (variable == "REMOTE_ADDR") { + else if (compareStrNoCase(variable, "REMOTE_ADDR")) { variableValue = transaction->m_variableRemoteAddr.resolveFirst(); } - else if (variable == "REMOTE_HOST") { + else if (compareStrNoCase(variable, "REMOTE_HOST")) { variableValue = transaction->m_variableRemoteHost.resolveFirst(); } - else if (variable == "REMOTE_PORT") { + else if (compareStrNoCase(variable, "REMOTE_PORT")) { variableValue = transaction->m_variableRemotePort.resolveFirst(); } - else if (variable == "REQBODY_ERROR") { + else if (compareStrNoCase(variable, "REQBODY_ERROR")) { variableValue = transaction->m_variableReqbodyError.resolveFirst(); } - else if (variable == "REQBODY_ERROR_MSG") { + else if (compareStrNoCase(variable, "REQBODY_ERROR_MSG")) { variableValue = transaction->m_variableReqbodyErrorMsg.resolveFirst(); } - else if (variable == "REQBODY_PROCESSOR_ERROR_MSG") { + else if (compareStrNoCase(variable, "REQBODY_PROCESSOR_ERROR_MSG")) { variableValue = transaction->m_variableReqbodyProcessorErrorMsg.resolveFirst(); } - else if (variable == "REQBODY_PROCESSOR_ERROR") { + else if (compareStrNoCase(variable, "REQBODY_PROCESSOR_ERROR")) { variableValue = transaction->m_variableReqbodyProcessorError.resolveFirst(); } - else if (variable == "REQBODY_PROCESSOR") { + else if (compareStrNoCase(variable, "REQBODY_PROCESSOR")) { variableValue = transaction->m_variableReqbodyProcessor.resolveFirst(); } - else if (variable == "REQUEST_BASENAME") { + else if (compareStrNoCase(variable, "REQUEST_BASENAME")) { variableValue = transaction->m_variableRequestBasename.resolveFirst(); } - else if (variable == "REQUEST_BODY") { + else if (compareStrNoCase(variable, "REQUEST_BODY")) { variableValue = transaction->m_variableRequestBody.resolveFirst(); } - else if (variable == "REQUEST_BODY_LENGTH") { + else if (compareStrNoCase(variable, "REQUEST_BODY_LENGTH")) { variableValue = transaction->m_variableRequestBodyLength.resolveFirst(); } - else if (variable == "REQUEST_FILENAME") { + else if (compareStrNoCase(variable, "REQUEST_FILENAME")) { variableValue = transaction->m_variableRequestFilename.resolveFirst(); } - else if (variable == "REQUEST_LINE") { + else if (compareStrNoCase(variable, "REQUEST_LINE")) { variableValue = transaction->m_variableRequestLine.resolveFirst(); } - else if (variable == "REQUEST_METHOD") { + else if (compareStrNoCase(variable, "REQUEST_METHOD")) { variableValue = transaction->m_variableRequestMethod.resolveFirst(); } - else if (variable == "REQUEST_PROTOCOL") { + else if (compareStrNoCase(variable, "REQUEST_PROTOCOL")) { variableValue = transaction->m_variableRequestProtocol.resolveFirst(); } - else if (variable == "REQUEST_URI") { + else if (compareStrNoCase(variable, "REQUEST_URI")) { variableValue = transaction->m_variableRequestURI.resolveFirst(); } - else if (variable == "REQUEST_URI_RAW") { + else if (compareStrNoCase(variable, "REQUEST_URI_RAW")) { variableValue = transaction->m_variableRequestURIRaw.resolveFirst(); } - else if (variable == "RESOURCE") { + else if (compareStrNoCase(variable, "RESOURCE")) { variableValue = transaction->m_variableResource.resolveFirst(); } - else if (variable == "RESPONSE_BODY") { + else if (compareStrNoCase(variable, "RESPONSE_BODY")) { variableValue = transaction->m_variableResponseBody.resolveFirst(); } - else if (variable == "RESPONSE_CONTENT_LENGTH") { + else if (compareStrNoCase(variable, "RESPONSE_CONTENT_LENGTH")) { variableValue = transaction->m_variableResponseContentLength.resolveFirst(); } - else if (variable == "RESPONSE_PROTOCOL") { + else if (compareStrNoCase(variable, "RESPONSE_PROTOCOL")) { variableValue = transaction->m_variableResponseProtocol.resolveFirst(); } - else if (variable == "RESPONSE_STATUS") { + else if (compareStrNoCase(variable, "RESPONSE_STATUS")) { variableValue = transaction->m_variableResponseStatus.resolveFirst(); } - else if (variable == "SERVER_ADDR") { + else if (compareStrNoCase(variable, "SERVER_ADDR")) { variableValue = transaction->m_variableServerAddr.resolveFirst(); } - else if (variable == "SERVER_NAME") { + else if (compareStrNoCase(variable, "SERVER_NAME")) { variableValue = transaction->m_variableServerName.resolveFirst(); } - else if (variable == "SERVER_PORT") { + else if (compareStrNoCase(variable, "SERVER_PORT")) { variableValue = transaction->m_variableServerPort.resolveFirst(); } - else if (variable == "SESSIONID") { + else if (compareStrNoCase(variable, "SESSIONID")) { variableValue = transaction->m_variableSessionID.resolveFirst(); } - else if (variable == "UNIQUE_ID") { + else if (compareStrNoCase(variable, "UNIQUE_ID")) { variableValue = transaction->m_variableUniqueID.resolveFirst(); } - else if (variable == "URLENCODED_ERROR") { + else if (compareStrNoCase(variable, "URLENCODED_ERROR")) { variableValue = transaction->m_variableUrlEncodedError.resolveFirst(); } - else if (variable == "USERID") { + else if (compareStrNoCase(variable, "USERID")) { variableValue = transaction->m_variableUserID.resolveFirst(); } else { variableValue = transaction->m_collections.resolveFirst( @@ -242,58 +241,58 @@ std::string MacroExpansion::expand(const std::string& input, std::string col = std::string(variable, 0, collection); std::string var = std::string(variable, collection + 1, variable.length() - (collection + 1)); - if (col == "ARGS") { + if (compareStrNoCase(col, "ARGS")) { variableValue = transaction->m_variableArgs.resolveFirst(var); } - else if (col == "RULE") { + else if (compareStrNoCase(col, "RULE")) { variableValue = transaction->m_variableRule.resolveFirst(var); } - else if (col == "ARGS_GET") { + else if (compareStrNoCase(col, "ARGS_GET")) { variableValue = transaction->m_variableArgsGet.resolveFirst(var); } - else if (col == "ARGS_POST") { + else if (compareStrNoCase(col, "ARGS_POST")) { variableValue = transaction->m_variableArgsPost.resolveFirst(var); } - else if (col == "FILES_SIZES") { + else if (compareStrNoCase(col, "FILES_SIZES")) { variableValue = transaction->m_variableFilesSizes.resolveFirst(var); } - else if (col == "FILES_NAMES") { + else if (compareStrNoCase(col, "FILES_NAMES")) { variableValue = transaction->m_variableFilesNames.resolveFirst(var); } - else if (col == "FILES_TMP_CONTENT") { + else if (compareStrNoCase(col, "FILES_TMP_CONTENT")) { variableValue = transaction->m_variableFilesTmpContent.resolveFirst(var); } - else if (col == "MULTIPART_FILENAME") { + else if (compareStrNoCase(col, "MULTIPART_FILENAME")) { variableValue = transaction->m_variableMultiPartFileName.resolveFirst(var); } - else if (col == "MULTIPART_NAME") { + else if (compareStrNoCase(col, "MULTIPART_NAME")) { variableValue = transaction->m_variableMultiPartName.resolveFirst(var); } - else if (col == "MATCHED_VARS_NAMES") { + else if (compareStrNoCase(col, "MATCHED_VARS_NAMES")) { variableValue = transaction->m_variableMatchedVarsNames.resolveFirst(var); } - else if (col == "MATCHED_VARS") { + else if (compareStrNoCase(col, "MATCHED_VARS")) { variableValue = transaction->m_variableMatchedVars.resolveFirst(var); } - else if (col == "FILES") { + else if (compareStrNoCase(col, "FILES")) { variableValue = transaction->m_variableFiles.resolveFirst(var); } - else if (col == "REQUEST_COOKIES") { + else if (compareStrNoCase(col, "REQUEST_COOKIES")) { variableValue = transaction->m_variableRequestCookies.resolveFirst(var); } - else if (col == "REQUEST_HEADERS") { + else if (compareStrNoCase(col, "REQUEST_HEADERS")) { variableValue = transaction->m_variableRequestHeaders.resolveFirst(var); } - else if (col == "RESPONSE_HEADERS") { + else if (compareStrNoCase(col, "RESPONSE_HEADERS")) { variableValue = transaction->m_variableResponseHeaders.resolveFirst(var); } - else if (col == "GEO") { + else if (compareStrNoCase(col, "GEO")) { variableValue = transaction->m_variableGeo.resolveFirst(var); } - else if (col == "REQUEST_COOKIES_NAMES") { + else if (compareStrNoCase(col, "REQUEST_COOKIES_NAMES")) { variableValue = transaction->m_variableRequestCookiesNames.resolveFirst(var); } - else if (col == "FILES_TMPNAMES") { + else if (compareStrNoCase(col, "FILES_TMPNAMES")) { variableValue = transaction->m_variableFilesTmpNames.resolveFirst(var); } else { variableValue = transaction->m_collections.resolveFirst(col, diff --git a/src/macro_expansion.h b/src/macro_expansion.h index f256929f..6613b5c1 100644 --- a/src/macro_expansion.h +++ b/src/macro_expansion.h @@ -38,6 +38,14 @@ class MacroExpansion { modsecurity::Rule *r, Transaction *transaction); static std::string expandKeepOriginal(const std::string& input, Transaction *transaction); + + static inline bool compareStrNoCase(const std::string &a, const std::string &b) { + return a.size() == b.size() + && std::equal(a.begin(), a.end(), b.begin(), + [](char aa, char bb) { + return toupper(aa) == bb; + }); + }; };