From e9563864a8e48fd5a5fe0cbd2fba4792bf1c1fff Mon Sep 17 00:00:00 2001 From: Luca Guerra Date: Tue, 14 Nov 2023 16:36:12 +0000 Subject: [PATCH 1/2] update(engine): port decode_uri in falco engine Signed-off-by: Luca Guerra --- userspace/engine/falco_utils.cpp | 76 ++++++++++++++++++++++++++++++++ userspace/engine/falco_utils.h | 2 + userspace/engine/json_evt.cpp | 4 +- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/userspace/engine/falco_utils.cpp b/userspace/engine/falco_utils.cpp index a52cf5918ea..25cf4ceb1a4 100644 --- a/userspace/engine/falco_utils.cpp +++ b/userspace/engine/falco_utils.cpp @@ -20,6 +20,7 @@ limitations under the License. #include #include +#include "falco_common.h" #include "falco_utils.h" #include "utils.h" @@ -159,6 +160,81 @@ void readfile(const std::string& filename, std::string& data) return; } + +// URI-decodes the given string by replacing percent-encoded +// characters with the actual character. Returns the decoded string. +// +// When plus_as_space is true, non-encoded plus signs in the query are decoded as spaces. +// (http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1) +std::string decode_uri(const std::string& str, bool plus_as_space) +{ + std::string decoded_str; + bool in_query = false; + std::string::const_iterator it = str.begin(); + std::string::const_iterator end = str.end(); + while(it != end) + { + char c = *it++; + if(c == '?') + { + in_query = true; + } + // spaces may be encoded as plus signs in the query + if(in_query && plus_as_space && c == '+') + { + c = ' '; + } + else if(c == '%') + { + if (it == end) + { + throw falco_exception("URI encoding: no hex digit following percent sign in " + str); + } + char hi = *it++; + if (it == end) + { + throw falco_exception("URI encoding: two hex digits must follow percent sign in " + str); + } + char lo = *it++; + if (hi >= '0' && hi <= '9') + { + c = hi - '0'; + } + else if (hi >= 'A' && hi <= 'F') + { + c = hi - 'A' + 10; + } + else if (hi >= 'a' && hi <= 'f') + { + c = hi - 'a' + 10; + } + else + { + throw falco_exception("URI encoding: not a hex digit found in " + str); + } + c *= 16; + if (lo >= '0' && lo <= '9') + { + c += lo - '0'; + } + else if (lo >= 'A' && lo <= 'F') + { + c += lo - 'A' + 10; + } + else if (lo >= 'a' && lo <= 'f') + { + c += lo - 'a' + 10; + } + else + { + throw falco_exception("URI encoding: not a hex digit"); + } + } + decoded_str += c; + } + return decoded_str; +} + namespace network { bool is_unix_scheme(const std::string& url) diff --git a/userspace/engine/falco_utils.h b/userspace/engine/falco_utils.h index 38bc5c9f6fa..81873077219 100644 --- a/userspace/engine/falco_utils.h +++ b/userspace/engine/falco_utils.h @@ -52,6 +52,8 @@ void readfile(const std::string& filename, std::string& data); uint32_t hardware_concurrency(); +std::string decode_uri(const std::string& str, bool plus_as_space); + namespace network { static const std::string UNIX_SCHEME("unix://"); diff --git a/userspace/engine/json_evt.cpp b/userspace/engine/json_evt.cpp index 4a48b80c335..5ba6e80d0c2 100644 --- a/userspace/engine/json_evt.cpp +++ b/userspace/engine/json_evt.cpp @@ -17,11 +17,11 @@ limitations under the License. #include -#include "uri.h" #include "utils.h" #include "falco_common.h" #include "json_evt.h" +#include "falco_utils.h" using json = nlohmann::json; using namespace std; @@ -1006,7 +1006,7 @@ bool k8s_audit_filter_check::extract_query_param(const nlohmann::json &j, { std::vector param_parts = sinsp_split(part, '='); - if(param_parts.size() == 2 && uri::decode(param_parts[0], true) == jchk.idx()) + if(param_parts.size() == 2 && falco::utils::decode_uri(param_parts[0], true) == jchk.idx()) { jchk.add_extracted_value(param_parts[1]); return true; From 45ef080d78c7f8cc614a380bb510c951dc45cb8d Mon Sep 17 00:00:00 2001 From: Luca Guerra Date: Tue, 14 Nov 2023 17:08:29 +0000 Subject: [PATCH 2/2] update(engine): add tests for decode_url() Signed-off-by: Luca Guerra --- unit_tests/engine/test_falco_utils.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/unit_tests/engine/test_falco_utils.cpp b/unit_tests/engine/test_falco_utils.cpp index e84cc661768..3dc1f770de4 100644 --- a/unit_tests/engine/test_falco_utils.cpp +++ b/unit_tests/engine/test_falco_utils.cpp @@ -72,3 +72,22 @@ TEST(FalcoUtils, parse_prometheus_interval) */ ASSERT_EQ(falco::utils::parse_prometheus_interval("200"), 0UL); } + +TEST(FalcoUtils, decode_url) +{ + ASSERT_EQ( + falco::utils::decode_uri("https://www.example.com?key1=value+1&key2=value%40%21%242&key3=value%253", true), + "https://www.example.com?key1=value 1&key2=value@!$2&key3=value%3"); + + ASSERT_EQ( + falco::utils::decode_uri("https://download.falco.org/?prefix=driver/3.0.1%2Bdriver/x86_64/", true), + "https://download.falco.org/?prefix=driver/3.0.1+driver/x86_64/"); + + ASSERT_EQ( + falco::utils::decode_uri("https://example.com/hello%20world", true), + "https://example.com/hello world"); + + ASSERT_EQ( + falco::utils::decode_uri("https://example.com/helloworld", true), + "https://example.com/helloworld"); +}