diff --git a/src/transaction.cc b/src/transaction.cc index bc28abe052..39ddd2d518 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -503,25 +503,12 @@ int Transaction::processURI(const char *uri, const char *method, m_variablePathInfo.set(path_info, m_variableOffset + strlen(method) + 1, var_size); - m_variableRequestFilename.set(path_info, m_variableOffset + - strlen(method) + 1, var_size); - - - size_t offset = path_info.find_last_of("/\\"); - if (offset != std::string::npos && path_info.length() > offset + 1) { - std::string basename = std::string(path_info, offset + 1, - path_info.length() - (offset + 1)); - m_variableRequestBasename.set(basename, m_variableOffset + - strlen(method) + 1 + offset + 1); - } - - m_variableOffset = m_variableRequestLine.m_value.size(); std::string parsedURI = m_uri_decoded; // The more popular case is without domain if (!m_uri_decoded.empty() && m_uri_decoded.at(0) != '/') { bool fullDomain = true; - size_t scheme = m_uri_decoded.find(":")+1; + size_t scheme = m_uri_decoded.find(":") + 1; if (scheme == std::string::npos) { fullDomain = false; } @@ -530,17 +517,32 @@ int Transaction::processURI(const char *uri, const char *method, // Assuming we found a colon make sure its followed size_t netloc = m_uri_decoded.find("//", scheme) + 2; if (netloc == std::string::npos || (netloc != scheme + 2)) { - fullDomain = false; + fullDomain = false; } if (netloc != std::string::npos && fullDomain == true) { - size_t path = m_uri_decoded.find("/", netloc); - if (path != std::string::npos) { - parsedURI = m_uri_decoded.substr(path); - } + size_t path = m_uri_decoded.find("/", netloc); + if (path != std::string::npos) { + parsedURI = m_uri_decoded.substr(path); + } } } } + m_variableRequestFilename.set( + path_info.substr(m_uri_decoded.size() - parsedURI.size()), + m_variableOffset + strlen(method) + 1, + var_size); + + size_t offset = path_info.find_last_of("/\\"); + if (offset != std::string::npos && path_info.length() > offset + 1) { + std::string basename = std::string(path_info, offset + 1, + path_info.length() - (offset + 1)); + m_variableRequestBasename.set( + basename, m_variableOffset + strlen(method) + 1 + offset + 1); + } + + m_variableOffset = m_variableRequestLine.m_value.size(); + m_variableRequestURI.set(parsedURI, std::string(method).size() + 1, uri_s.size()); m_variableRequestURIRaw.set(uri, std::string(method).size() + 1); diff --git a/test/test-cases/regression/variable-REQUEST_FILENAME.json b/test/test-cases/regression/variable-REQUEST_FILENAME.json index 5a41c29e7d..de8a938e12 100644 --- a/test/test-cases/regression/variable-REQUEST_FILENAME.json +++ b/test/test-cases/regression/variable-REQUEST_FILENAME.json @@ -39,5 +39,47 @@ "SecRuleEngine On", "SecRule REQUEST_FILENAME \"@contains test \" \"id:1,phase:3,pass,t:trim\"" ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: REQUEST_FILENAME with domain", + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "server":{ + "ip":"200.249.12.11", + "port":80 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*", + "Content-Length":"27", + "Content-Type":"application/x-www-form-urlencoded" + }, + "uri":"https://apple.com/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202", + "method":"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":{ + "http_code": 403, + "debug_log":"Target value: \"/one/two/login.php\" \\(Variable: REQUEST_FILENAME\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"@streq /one/two/login.php\" \"id:1,phase:3,deny,status:403,t:trim\"" + ] } ]