From b8160cce6b00727f871d85f11a418cbda37b7890 Mon Sep 17 00:00:00 2001 From: martinhsv <55407942+martinhsv@users.noreply.github.com> Date: Thu, 14 Nov 2019 08:14:04 -0800 Subject: [PATCH] Fix Cookie header parsing issues --- CHANGES | 2 + src/transaction.cc | 11 ++++ .../regression/variable-REQUEST_COOKIES.json | 50 +++++++++++++++++-- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 0fe40643..943ae6ea 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ v3.0.4 - YYYY-MMM-DD (to be released) ------------------------------------- + - Fix Cookie header parsing issues + [Issue #2201 - @airween, @martinhsv] - Fix rules with nolog are logging to part H [Issue #2196 - @martinhsv] - Fix argument key-value pair parsing cases diff --git a/src/transaction.cc b/src/transaction.cc index 61261cad..16361b70 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -549,7 +549,18 @@ int Transaction::addRequestHeader(const std::string& key, if (keyl == "cookie") { size_t localOffset = m_variableOffset; size_t pos; + std::vector cookies = utils::string::ssplit(value, ';'); + + // Get rid of any optional whitespace after the cookie-string + // (i.e. after the end of the final cookie-pair) + if (!cookies.empty()) { + std::string& final_cookie_pair = cookies.back(); + while (!final_cookie_pair.empty() && isspace(final_cookie_pair.back())) { + final_cookie_pair.pop_back(); + } + } + for (const std::string &c : cookies) { // skip empty substring, eg "Cookie: ;;foo=bar" if (c.empty() == true) { diff --git a/test/test-cases/regression/variable-REQUEST_COOKIES.json b/test/test-cases/regression/variable-REQUEST_COOKIES.json index 1ae9268f..f5a9b49b 100644 --- a/test/test-cases/regression/variable-REQUEST_COOKIES.json +++ b/test/test-cases/regression/variable-REQUEST_COOKIES.json @@ -2,7 +2,7 @@ { "enabled":1, "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (1/5)", + "title":"Testing Variables :: REQUEST_COOKIES (1/6)", "client":{ "ip":"200.249.12.31", "port":123 @@ -42,7 +42,7 @@ { "enabled":1, "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (2/5)", + "title":"Testing Variables :: REQUEST_COOKIES (2/6)", "client":{ "ip":"200.249.12.31", "port":123 @@ -82,7 +82,7 @@ { "enabled":1, "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (3/5)", + "title":"Testing Variables :: REQUEST_COOKIES (3/6)", "client":{ "ip":"200.249.12.31", "port":123 @@ -122,7 +122,7 @@ { "enabled":1, "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (4/5)", + "title":"Testing Variables :: REQUEST_COOKIES (4/6)", "client":{ "ip":"200.249.12.31", "port":123 @@ -162,7 +162,7 @@ { "enabled":1, "version_min":300000, - "title":"Testing Variables :: REQUEST_COOKIES (5/5)", + "title":"Testing Variables :: REQUEST_COOKIES (5/6)", "client":{ "ip":"200.249.12.31", "port":123 @@ -198,6 +198,46 @@ "SecRuleEngine On", "SecRule REQUEST_COOKIES \"@contains test \" \"id:1,pass,t:trim\"" ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing Variables :: REQUEST_COOKIES (6/6)", + "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":"*/*", + "Cookie":"aaa=bbb;abc=def " + }, + "uri":"/?key=value&key=other_value", + "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":{ + "debug_log":"Target value: \"def\" \\(Variable: REQUEST_COOKIES:abc\\)" + }, + "rules":[ + "SecRuleEngine On", + "SecRule REQUEST_COOKIES:abc \"@rx ^def$\" \"id:1,pass\"" + ] } ]