From 8ac704804c5ecdc6809abd1021a51b77023883e1 Mon Sep 17 00:00:00 2001 From: Anil Mahtani <929854+Anilm3@users.noreply.github.com> Date: Wed, 10 May 2023 17:25:57 +0100 Subject: [PATCH 1/3] Support for per-input transformers --- src/condition.cpp | 24 ++-- src/condition.hpp | 21 ++-- src/parser/parser_v1.cpp | 3 +- src/parser/parser_v2.cpp | 64 ++++++---- tests/collection_test.cpp | 80 ++++++------- tests/condition_test.cpp | 22 ++-- tests/context_test.cpp | 230 ++++++++++++++++++------------------ tests/input_filter_test.cpp | 112 +++++++++--------- tests/rule_filter_test.cpp | 56 ++++----- tests/rule_test.cpp | 60 +++++----- 10 files changed, 345 insertions(+), 327 deletions(-) diff --git a/src/condition.cpp b/src/condition.cpp index 1206fe8ba..6fd33a7ee 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -12,17 +12,18 @@ namespace ddwaf { -std::optional condition::match_object( - const ddwaf_object *object, const rule_processor::base::ptr &processor) const +std::optional condition::match_object(const ddwaf_object *object, + const rule_processor::base::ptr &processor, + const std::vector &transformers) const { - const bool has_transform = !transformers_.empty(); + const bool has_transform = !transformers.empty(); bool transform_required = false; if (has_transform) { // This codepath is shared with the mutable path. The structure can't be const :/ transform_required = // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - PWTransformer::doesNeedTransform(transformers_, const_cast(object)); + PWTransformer::doesNeedTransform(transformers, const_cast(object)); } const size_t length = @@ -42,7 +43,7 @@ std::optional condition::match_object( // Transform it and pick the pointer to process bool transformFailed = false; - for (const PW_TRANSFORM_ID &transform : transformers_) { + for (const PW_TRANSFORM_ID &transform : transformers) { transformFailed = !PWTransformer::transform(transform, ©); if (transformFailed || (copy.type == DDWAF_OBJ_STRING && copy.nbEntries == 0)) { break; @@ -57,8 +58,9 @@ std::optional condition::match_object( } template -std::optional condition::match_target( - T &it, const rule_processor::base::ptr &processor, ddwaf::timer &deadline) const +std::optional condition::match_target(T &it, + const rule_processor::base::ptr &processor, const std::vector &transformers, + ddwaf::timer &deadline) const { for (; it; ++it) { if (deadline.expired()) { @@ -69,7 +71,7 @@ std::optional condition::match_target( continue; } - auto optional_match = match_object(*it, processor); + auto optional_match = match_object(*it, processor, transformers); if (!optional_match.has_value()) { continue; } @@ -108,7 +110,7 @@ std::optional condition::match(const object_store &store, return std::nullopt; } - for (const auto &[target, name, key_path] : targets_) { + for (const auto &[target, name, key_path, transformers] : targets_) { if (deadline.expired()) { throw ddwaf::timeout_exception(); } @@ -128,10 +130,10 @@ std::optional condition::match(const object_store &store, std::optional optional_match; if (source_ == data_source::keys) { object::key_iterator it(object, key_path, objects_excluded, limits_); - optional_match = match_target(it, processor, deadline); + optional_match = match_target(it, processor, transformers, deadline); } else { object::value_iterator it(object, key_path, objects_excluded, limits_); - optional_match = match_target(it, processor, deadline); + optional_match = match_target(it, processor, transformers, deadline); } if (optional_match.has_value()) { diff --git a/src/condition.hpp b/src/condition.hpp index 8b5721065..8cff98e0d 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -31,17 +31,16 @@ class condition { manifest::target_type root; std::string name; std::vector key_path; + std::vector transformers; }; enum class data_source : uint8_t { values, keys }; - condition(std::vector targets, std::vector transformers, - std::shared_ptr processor, std::string data_id = {}, - ddwaf::object_limits limits = ddwaf::object_limits(), + condition(std::vector targets, std::shared_ptr processor, + std::string data_id = {}, ddwaf::object_limits limits = ddwaf::object_limits(), data_source source = data_source::values) - : targets_(std::move(targets)), transformers_(std::move(transformers)), - processor_(std::move(processor)), data_id_(std::move(data_id)), limits_(limits), - source_(source) + : targets_(std::move(targets)), processor_(std::move(processor)), + data_id_(std::move(data_id)), limits_(limits), source_(source) {} ~condition() = default; @@ -62,17 +61,17 @@ class condition { } protected: - std::optional match_object( - const ddwaf_object *object, const rule_processor::base::ptr &processor) const; + std::optional match_object(const ddwaf_object *object, + const rule_processor::base::ptr &processor, + const std::vector &transformers) const; template - std::optional match_target( - T &it, const rule_processor::base::ptr &processor, ddwaf::timer &deadline) const; + std::optional match_target(T &it, const rule_processor::base::ptr &processor, + const std::vector &transformers, ddwaf::timer &deadline) const; [[nodiscard]] const rule_processor::base::ptr &get_processor( const std::unordered_map &dynamic_processors) const; std::vector targets_; - std::vector transformers_; std::shared_ptr processor_; std::string data_id_; ddwaf::object_limits limits_; diff --git a/src/parser/parser_v1.cpp b/src/parser/parser_v1.cpp index 2127e8a0b..1c1ab94e4 100644 --- a/src/parser/parser_v1.cpp +++ b/src/parser/parser_v1.cpp @@ -100,11 +100,12 @@ condition::ptr parseCondition(parameter::map &rule, manifest &target_manifest, if (!key_path.empty()) { target.key_path.emplace_back(key_path); } + target.transformers = transformers; targets.emplace_back(std::move(target)); } return std::make_shared( - std::move(targets), std::move(transformers), std::move(processor), std::string{}, limits); + std::move(targets), std::move(processor), std::string{}, limits); } void parseRule(parameter::map &rule, base_section_info &info, manifest &target_manifest, diff --git a/src/parser/parser_v2.cpp b/src/parser/parser_v2.cpp index ddd414f5e..c0ec08989 100644 --- a/src/parser/parser_v2.cpp +++ b/src/parser/parser_v2.cpp @@ -100,9 +100,38 @@ std::pair parse_processor( return {std::move(rule_data_id), std::move(processor)}; } +std::vector parse_transformers( + const parameter::vector &root, condition::data_source &source) +{ + if (root.empty()) { + return {}; + } + + std::vector transformers; + transformers.reserve(root.size()); + + for (const auto &transformer_param : root) { + auto transformer = static_cast(transformer_param); + PW_TRANSFORM_ID transform_id = PWTransformer::getIDForString(transformer); + switch (transform_id) { + case PWT_KEYS_ONLY: + source = ddwaf::condition::data_source::keys; + break; + case PWT_VALUES_ONLY: + source = ddwaf::condition::data_source::values; + break; + case PWT_INVALID: + throw ddwaf::parsing_error("invalid transformer " + std::string(transformer)); + default: + transformers.push_back(transform_id); + } + } + return transformers; +} + condition::ptr parse_rule_condition(const parameter::map &root, manifest &target_manifest, std::unordered_map &rule_data_ids, condition::data_source source, - std::vector transformers, const object_limits &limits) + const std::vector &transformers, const object_limits &limits) { auto operation = at(root, "operator"); auto params = at(root, "parameters"); @@ -136,12 +165,18 @@ condition::ptr parse_rule_condition(const parameter::map &root, manifest &target target.root = target_manifest.insert(address); target.name = address; target.key_path = std::move(kp); + auto input_transformers = at(input, "transformers", {}); + if (input_transformers.empty()) { + target.transformers = transformers; + } else { + target.transformers = parse_transformers(input_transformers, source); + } targets.emplace_back(target); } - return std::make_shared(std::move(targets), std::move(transformers), - std::move(processor), std::move(rule_data_id), limits, source); + return std::make_shared( + std::move(targets), std::move(processor), std::move(rule_data_id), limits, source); } rule_spec parse_rule(parameter::map &rule, manifest &target_manifest, @@ -151,24 +186,7 @@ rule_spec parse_rule(parameter::map &rule, manifest &target_manifest, std::vector rule_transformers; auto data_source = ddwaf::condition::data_source::values; auto transformers = at(rule, "transformers", {}); - for (const auto &transformer_param : transformers) { - auto transformer = static_cast(transformer_param); - PW_TRANSFORM_ID transform_id = PWTransformer::getIDForString(transformer); - if (transform_id == PWT_INVALID) { - throw ddwaf::parsing_error("invalid transformer " + std::string(transformer)); - } - - if (transform_id == PWT_KEYS_ONLY) { - if (!rule_transformers.empty()) { - DDWAF_WARN("keys_only transformer should be the first one " - "in the list, all transformers will be applied to " - "keys and not values"); - } - data_source = ddwaf::condition::data_source::keys; - } else { - rule_transformers.push_back(transform_id); - } - } + rule_transformers = parse_transformers(transformers, data_source); std::vector conditions; auto conditions_array = at(rule, "conditions"); @@ -301,8 +319,8 @@ condition::ptr parse_filter_condition( targets.emplace_back(target); } - return std::make_shared(std::move(targets), std::vector{}, - std::move(processor), std::string{}, limits); + return std::make_shared( + std::move(targets), std::move(processor), std::string{}, limits); } input_filter_spec parse_input_filter( diff --git a/tests/collection_test.cpp b/tests/collection_test.cpp index da51ac1a7..34bebbb15 100644 --- a/tests/collection_test.cpp +++ b/tests/collection_test.cpp @@ -20,9 +20,9 @@ TYPED_TEST(TestCollection, SingleRuleMatch) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -75,11 +75,11 @@ TYPED_TEST(TestCollection, MultipleRuleCachedMatch) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -95,9 +95,9 @@ TYPED_TEST(TestCollection, MultipleRuleCachedMatch) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -153,11 +153,11 @@ TYPED_TEST(TestCollection, MultipleRuleFailAndMatch) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -172,9 +172,9 @@ TYPED_TEST(TestCollection, MultipleRuleFailAndMatch) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -228,21 +228,19 @@ TYPED_TEST(TestCollection, SingleRuleMultipleCalls) std::vector conditions; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - conditions.emplace_back( - std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"}))); + conditions.emplace_back(std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"}))); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - conditions.emplace_back( - std::make_shared(std::move(targets), std::vector{}, - std::make_unique(std::vector{"admin"}))); + conditions.emplace_back(std::make_shared(std::move(targets), + std::make_unique(std::vector{"admin"}))); } std::unordered_map tags{{"type", "type"}, {"category", "category"}}; @@ -296,11 +294,11 @@ TEST(TestPriorityCollection, NoRegularMatchAfterPriorityMatch) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -315,9 +313,9 @@ TEST(TestPriorityCollection, NoRegularMatchAfterPriorityMatch) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -376,11 +374,11 @@ TEST(TestPriorityCollection, PriorityMatchAfterRegularMatch) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -395,9 +393,9 @@ TEST(TestPriorityCollection, PriorityMatchAfterRegularMatch) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -456,11 +454,11 @@ TEST(TestPriorityCollection, NoPriorityMatchAfterPriorityMatch) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -475,9 +473,9 @@ TEST(TestPriorityCollection, NoPriorityMatchAfterPriorityMatch) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; diff --git a/tests/condition_test.cpp b/tests/condition_test.cpp index 115a314d8..4430c48cc 100644 --- a/tests/condition_test.cpp +++ b/tests/condition_test.cpp @@ -13,10 +13,10 @@ TEST(TestCondition, Match) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique(".*", 0, true)); + auto cond = std::make_shared( + std::move(targets), std::make_unique(".*", 0, true)); ddwaf_object root; ddwaf_object tmp; @@ -44,9 +44,9 @@ TEST(TestCondition, NoMatch) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{})); ddwaf_object root; @@ -68,10 +68,10 @@ TEST(TestCondition, ExcludeInput) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique(".*", 0, true)); + auto cond = std::make_shared( + std::move(targets), std::make_unique(".*", 0, true)); ddwaf_object root; ddwaf_object tmp; @@ -92,10 +92,10 @@ TEST(TestCondition, ExcludeKeyPath) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique(".*", 0, true)); + auto cond = std::make_shared( + std::move(targets), std::make_unique(".*", 0, true)); ddwaf_object root; ddwaf_object map; diff --git a/tests/context_test.cpp b/tests/context_test.cpp index 93e884bde..e41e6f51b 100644 --- a/tests/context_test.cpp +++ b/tests/context_test.cpp @@ -25,9 +25,9 @@ TEST(TestContext, MatchTimeout) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -58,9 +58,9 @@ TEST(TestContext, NoMatch) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -92,9 +92,9 @@ TEST(TestContext, Match) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -127,11 +127,11 @@ TEST(TestContext, MatchMultipleRulesInCollectionSingleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -146,9 +146,9 @@ TEST(TestContext, MatchMultipleRulesInCollectionSingleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -201,11 +201,11 @@ TEST(TestContext, MatchMultipleRulesWithPrioritySingleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -220,9 +220,9 @@ TEST(TestContext, MatchMultipleRulesWithPrioritySingleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -286,11 +286,11 @@ TEST(TestContext, MatchMultipleRulesInCollectionDoubleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -305,9 +305,9 @@ TEST(TestContext, MatchMultipleRulesInCollectionDoubleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -372,11 +372,11 @@ TEST(TestContext, MatchMultipleRulesWithPriorityDoubleRunPriorityLast) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -391,9 +391,9 @@ TEST(TestContext, MatchMultipleRulesWithPriorityDoubleRunPriorityLast) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -478,11 +478,11 @@ TEST(TestContext, MatchMultipleRulesWithPriorityDoubleRunPriorityFirst) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -497,9 +497,9 @@ TEST(TestContext, MatchMultipleRulesWithPriorityDoubleRunPriorityFirst) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -566,11 +566,11 @@ TEST(TestContext, MatchMultipleRulesWithPriorityUntilAllActionsMet) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -585,9 +585,9 @@ TEST(TestContext, MatchMultipleRulesWithPriorityUntilAllActionsMet) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -670,11 +670,11 @@ TEST(TestContext, MatchMultipleCollectionsSingleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -689,9 +689,9 @@ TEST(TestContext, MatchMultipleCollectionsSingleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -727,11 +727,11 @@ TEST(TestContext, MatchMultiplePriorityCollectionsSingleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -746,9 +746,9 @@ TEST(TestContext, MatchMultiplePriorityCollectionsSingleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -784,11 +784,11 @@ TEST(TestContext, MatchMultipleCollectionsDoubleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -803,9 +803,9 @@ TEST(TestContext, MatchMultipleCollectionsDoubleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -853,11 +853,11 @@ TEST(TestContext, MatchMultiplePriorityCollectionsDoubleRun) ddwaf::manifest manifest; { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -872,9 +872,9 @@ TEST(TestContext, MatchMultiplePriorityCollectionsDoubleRun) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -925,9 +925,9 @@ TEST(TestContext, RuleFilterWithCondition) ddwaf::rule::ptr rule; { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -944,11 +944,11 @@ TEST(TestContext, RuleFilterWithCondition) // Generate filter { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -986,9 +986,9 @@ TEST(TestContext, RuleFilterTimeout) ddwaf::rule::ptr rule; { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -1005,11 +1005,11 @@ TEST(TestContext, RuleFilterTimeout) // Generate filter { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1042,9 +1042,9 @@ TEST(TestContext, NoRuleFilterWithCondition) ddwaf::rule::ptr rule; { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -1061,11 +1061,11 @@ TEST(TestContext, NoRuleFilterWithCondition) // Generate filter { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1302,11 +1302,11 @@ TEST(TestContext, MultipleRuleFiltersNonOverlappingRulesWithConditions) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1318,9 +1318,9 @@ TEST(TestContext, MultipleRuleFiltersNonOverlappingRulesWithConditions) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -1397,11 +1397,11 @@ TEST(TestContext, MultipleRuleFiltersOverlappingRulesWithConditions) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1413,9 +1413,9 @@ TEST(TestContext, MultipleRuleFiltersOverlappingRulesWithConditions) { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); std::vector> conditions{std::move(cond)}; @@ -1474,7 +1474,7 @@ TEST(TestContext, InputFilterExclude) condition::target_type client_ip{manifest.insert("http.client_ip"), "http.client_ip", {}}; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1518,7 +1518,7 @@ TEST(TestContext, InputFilterExcludeRule) condition::target_type client_ip{manifest.insert("http.client_ip"), "http.client_ip", {}}; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -1569,9 +1569,9 @@ TEST(TestContext, InputFilterWithCondition) { std::vector> conditions; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.emplace_back(std::move(cond)); std::unordered_map tags{ @@ -1589,7 +1589,7 @@ TEST(TestContext, InputFilterWithCondition) std::vector> conditions; std::vector targets{usr_id}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.emplace_back(std::move(cond)); @@ -1666,9 +1666,9 @@ TEST(TestContext, InputFilterMultipleRules) { std::vector> conditions; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.emplace_back(std::move(cond)); std::unordered_map tags{ @@ -1683,7 +1683,7 @@ TEST(TestContext, InputFilterMultipleRules) { std::vector> conditions; std::vector targets{usr_id}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.emplace_back(std::move(cond)); @@ -1781,9 +1781,9 @@ TEST(TestContext, InputFilterMultipleRulesMultipleFilters) { std::vector> conditions; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.emplace_back(std::move(cond)); std::unordered_map tags{ @@ -1798,7 +1798,7 @@ TEST(TestContext, InputFilterMultipleRulesMultipleFilters) { std::vector> conditions; std::vector targets{usr_id}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.emplace_back(std::move(cond)); @@ -1909,9 +1909,9 @@ TEST(TestContext, InputFilterMultipleRulesMultipleFiltersMultipleObjects) { std::vector> conditions; std::vector targets{client_ip}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.emplace_back(std::move(cond)); std::unordered_map tags{ @@ -1926,7 +1926,7 @@ TEST(TestContext, InputFilterMultipleRulesMultipleFiltersMultipleObjects) { std::vector> conditions; std::vector targets{usr_id}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.emplace_back(std::move(cond)); @@ -1942,7 +1942,7 @@ TEST(TestContext, InputFilterMultipleRulesMultipleFiltersMultipleObjects) { std::vector> conditions; std::vector targets{cookie_header}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"mycookie"})); conditions.emplace_back(std::move(cond)); diff --git a/tests/input_filter_test.cpp b/tests/input_filter_test.cpp index 822c3d025..5eaa3b0fa 100644 --- a/tests/input_filter_test.cpp +++ b/tests/input_filter_test.cpp @@ -75,8 +75,8 @@ TEST(TestInputFilter, InputExclusionWithCondition) ddwaf::manifest manifest; auto client_ip = manifest.insert("http.client_ip"); - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -109,8 +109,8 @@ TEST(TestInputFilter, InputExclusionFailedCondition) ddwaf::manifest manifest; auto client_ip = manifest.insert("http.client_ip"); - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -141,8 +141,8 @@ TEST(TestInputFilter, ObjectExclusionWithCondition) auto client_ip = manifest.insert("http.client_ip"); auto query = manifest.insert("query"); - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -182,8 +182,8 @@ TEST(TestInputFilter, ObjectExclusionFailedCondition) auto client_ip = manifest.insert("http.client_ip"); auto query = manifest.insert("query"); - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -222,16 +222,16 @@ TEST(TestInputFilter, InputValidateCachedMatch) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -284,16 +284,16 @@ TEST(TestInputFilter, InputMatchWithoutCache) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -342,16 +342,16 @@ TEST(TestInputFilter, InputNoMatchWithoutCache) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -407,16 +407,16 @@ TEST(TestInputFilter, InputCachedMatchSecondRun) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -471,16 +471,16 @@ TEST(TestInputFilter, ObjectValidateCachedMatch) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -543,16 +543,16 @@ TEST(TestInputFilter, ObjectMatchWithoutCache) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -612,16 +612,16 @@ TEST(TestInputFilter, ObjectNoMatchWithoutCache) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -680,16 +680,16 @@ TEST(TestInputFilter, ObjectCachedMatchSecondRun) std::vector> conditions; { - std::vector targets{{client_ip, "http.client_ip", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + std::vector targets{{client_ip, "http.client_ip", {}, {}}}; + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { - std::vector targets{{usr_id, "usr.id", {}}}; - auto cond = std::make_shared(std::move(targets), std::vector{}, + std::vector targets{{usr_id, "usr.id", {}, {}}}; + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } diff --git a/tests/rule_filter_test.cpp b/tests/rule_filter_test.cpp index 8a8d256dc..64aef6ab1 100644 --- a/tests/rule_filter_test.cpp +++ b/tests/rule_filter_test.cpp @@ -13,9 +13,9 @@ TEST(TestRuleFilter, Match) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -41,9 +41,9 @@ TEST(TestRuleFilter, NoMatch) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{})); std::vector> conditions{std::move(cond)}; @@ -70,17 +70,17 @@ TEST(TestRuleFilter, ValidateCachedMatch) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -125,17 +125,17 @@ TEST(TestRuleFilter, MatchWithoutCache) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -179,17 +179,17 @@ TEST(TestRuleFilter, NoMatchWithoutCache) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -233,17 +233,17 @@ TEST(TestRuleFilter, FullCachedMatchSecondRun) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } diff --git a/tests/rule_test.cpp b/tests/rule_test.cpp index e723c3e1b..482d9ae75 100644 --- a/tests/rule_test.cpp +++ b/tests/rule_test.cpp @@ -13,9 +13,9 @@ TEST(TestRule, Match) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; @@ -59,9 +59,9 @@ TEST(TestRule, NoMatch) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{})); std::vector> conditions{std::move(cond)}; @@ -89,17 +89,17 @@ TEST(TestRule, ValidateCachedMatch) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -171,17 +171,17 @@ TEST(TestRule, MatchWithoutCache) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -247,17 +247,17 @@ TEST(TestRule, NoMatchWithoutCache) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -304,17 +304,17 @@ TEST(TestRule, FullCachedMatchSecondRun) { std::vector targets; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, - std::make_unique( - std::vector{"192.168.0.1"})); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + auto cond = std::make_shared( + std::move(targets), std::make_unique( + std::vector{"192.168.0.1"})); conditions.push_back(std::move(cond)); } { std::vector targets; - targets.push_back({manifest.insert("usr.id"), "usr.id", {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + targets.push_back({manifest.insert("usr.id"), "usr.id", {}, {}}); + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"admin"})); conditions.push_back(std::move(cond)); } @@ -361,9 +361,9 @@ TEST(TestRule, ExcludeObject) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); - auto cond = std::make_shared(std::move(targets), std::vector{}, + auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{"192.168.0.1"})); std::vector> conditions{std::move(cond)}; From 0e459d0d72d44aab4ee7e7eba1be569770da4e78 Mon Sep 17 00:00:00 2001 From: Anil Mahtani <929854+Anilm3@users.noreply.github.com> Date: Thu, 11 May 2023 14:24:00 +0100 Subject: [PATCH 2/3] Tests --- tests/condition_test.cpp | 100 +++++++++++++ tests/integration/conditions/test.cpp | 140 ++++++++++++++++++ .../conditions/yaml/global_transformer.yaml | 39 +++++ .../conditions/yaml/input_transformer.yaml | 37 +++++ 4 files changed, 316 insertions(+) create mode 100644 tests/integration/conditions/test.cpp create mode 100644 tests/integration/conditions/yaml/global_transformer.yaml create mode 100644 tests/integration/conditions/yaml/input_transformer.yaml diff --git a/tests/condition_test.cpp b/tests/condition_test.cpp index 4430c48cc..dc41a2f31 100644 --- a/tests/condition_test.cpp +++ b/tests/condition_test.cpp @@ -39,6 +39,106 @@ TEST(TestCondition, Match) EXPECT_TRUE(match->key_path.empty()); } +TEST(TestCondition, MatchWithKeyPath) +{ + std::vector targets; + + ddwaf::manifest manifest; + targets.push_back( + {manifest.insert("server.request.query"), "server.request.query", {"key"}, {}}); + + auto cond = std::make_shared( + std::move(targets), std::make_unique(".*", 0, true)); + + ddwaf_object root; + ddwaf_object submap; + ddwaf_object tmp; + ddwaf_object_map(&submap); + ddwaf_object_map_add(&submap, "key", ddwaf_object_string(&tmp, "value")); + ddwaf_object_map(&root); + ddwaf_object_map_add(&root, "server.request.query", &submap); + + ddwaf::object_store store(manifest); + store.insert(root); + + ddwaf::timer deadline{2s}; + + auto match = cond->match(store, {}, true, {}, deadline); + EXPECT_TRUE(match.has_value()); + + EXPECT_STREQ(match->resolved.c_str(), "value"); + EXPECT_STREQ(match->matched.c_str(), "value"); + EXPECT_STREQ(match->operator_name.data(), "match_regex"); + EXPECT_STREQ(match->operator_value.data(), ".*"); + EXPECT_STREQ(match->address.data(), "server.request.query"); + EXPECT_EQ(match->key_path.size(), 1); + EXPECT_STREQ(match->key_path[0].data(), "key"); +} + +TEST(TestCondition, MatchWithTransformer) +{ + std::vector targets; + + ddwaf::manifest manifest; + targets.push_back( + {manifest.insert("server.request.query"), "server.request.query", {}, {PWT_LOWERCASE}}); + + auto cond = std::make_shared( + std::move(targets), std::make_unique("value", 0, true)); + + ddwaf_object root; + ddwaf_object tmp; + ddwaf_object_map(&root); + ddwaf_object_map_add(&root, "server.request.query", ddwaf_object_string(&tmp, "VALUE")); + + ddwaf::object_store store(manifest); + store.insert(root); + + ddwaf::timer deadline{2s}; + + auto match = cond->match(store, {}, true, {}, deadline); + EXPECT_TRUE(match.has_value()); + + EXPECT_STREQ(match->resolved.c_str(), "value"); + EXPECT_STREQ(match->matched.c_str(), "value"); + EXPECT_STREQ(match->operator_name.data(), "match_regex"); + EXPECT_STREQ(match->operator_value.data(), "value"); + EXPECT_STREQ(match->address.data(), "server.request.query"); + EXPECT_TRUE(match->key_path.empty()); +} + +TEST(TestCondition, MatchWithMultipleTransformers) +{ + std::vector targets; + + ddwaf::manifest manifest; + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, + {PWT_COMPRESS_WHITE, PWT_LOWERCASE}}); + + auto cond = std::make_shared( + std::move(targets), std::make_unique("^ value $", 0, true)); + + ddwaf_object root; + ddwaf_object tmp; + ddwaf_object_map(&root); + ddwaf_object_map_add(&root, "server.request.query", ddwaf_object_string(&tmp, " VALUE ")); + + ddwaf::object_store store(manifest); + store.insert(root); + + ddwaf::timer deadline{2s}; + + auto match = cond->match(store, {}, true, {}, deadline); + EXPECT_TRUE(match.has_value()); + + EXPECT_STREQ(match->resolved.c_str(), " value "); + EXPECT_STREQ(match->matched.c_str(), " value "); + EXPECT_STREQ(match->operator_name.data(), "match_regex"); + EXPECT_STREQ(match->operator_value.data(), "^ value $"); + EXPECT_STREQ(match->address.data(), "server.request.query"); + EXPECT_TRUE(match->key_path.empty()); +} + TEST(TestCondition, NoMatch) { std::vector targets; diff --git a/tests/integration/conditions/test.cpp b/tests/integration/conditions/test.cpp new file mode 100644 index 000000000..e97824818 --- /dev/null +++ b/tests/integration/conditions/test.cpp @@ -0,0 +1,140 @@ +// Unless explicitly stated otherwise all files in this repository are +// dual-licensed under the Apache-2.0 License or BSD-3-Clause License. +// +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2021 Datadog, Inc. + +#include "../../test.h" +#include "ddwaf.h" + +using namespace ddwaf; + +namespace { +constexpr std::string_view base_dir = "integration/conditions/"; +} // namespace + +TEST(TestConditionsIntegration, GlobalTransformer) +{ + auto rule = readFile("global_transformer.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_0", ddwaf_object_string(&tmp, "RULE1")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_1", ddwaf_object_string(&tmp, "RULE1")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value2_0", ddwaf_object_string(&tmp, " RULE2 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value2_1", ddwaf_object_string(&tmp, " RULE2 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} + +TEST(TestConditionsIntegration, InputTransformer) +{ + auto rule = readFile("input_transformer.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_0", ddwaf_object_string(&tmp, "RULE1")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_1", ddwaf_object_string(&tmp, "RULE1")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value2_0", ddwaf_object_string(&tmp, " RULE2 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value2_1", ddwaf_object_string(&tmp, " RULE2 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} diff --git a/tests/integration/conditions/yaml/global_transformer.yaml b/tests/integration/conditions/yaml/global_transformer.yaml new file mode 100644 index 000000000..24a259378 --- /dev/null +++ b/tests/integration/conditions/yaml/global_transformer.yaml @@ -0,0 +1,39 @@ +version: '2.1' +rules: + - id: rule1 + name: rule1 + tags: + type: flow1 + category: category1 + confidence: 1 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value1_0 + - address: value1_1 + regex: rule1 + options: + case_sensitive: true + transformers: + - lowercase + + - id: rule2 + name: rule2 + tags: + type: flow2 + category: category2 + confidence: 1000 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value2_0 + - address: value2_1 + regex: ^ rule2 $ + options: + case_sensitive: true + transformers: + - lowercase + - compressWhiteSpace + diff --git a/tests/integration/conditions/yaml/input_transformer.yaml b/tests/integration/conditions/yaml/input_transformer.yaml new file mode 100644 index 000000000..d5ec77d1c --- /dev/null +++ b/tests/integration/conditions/yaml/input_transformer.yaml @@ -0,0 +1,37 @@ +version: '2.1' +rules: + - id: rule1 + name: rule1 + tags: + type: flow1 + category: category1 + confidence: 1 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value1_0 + transformers: + - lowercase + - address: value1_1 + regex: rule1 + options: + case_sensitive: true + - id: rule2 + name: rule2 + tags: + type: flow2 + category: category2 + confidence: 1000 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value2_0 + transformers: + - lowercase + - compressWhiteSpace + - address: value2_1 + regex: ^ rule2 $ + options: + case_sensitive: true From f8235dab03403424e07d0cb359a09aacad5c4331 Mon Sep 17 00:00:00 2001 From: Anil Mahtani <929854+Anilm3@users.noreply.github.com> Date: Mon, 15 May 2023 13:45:48 +0100 Subject: [PATCH 3/3] Make data source input specific --- src/PWTransformer.cpp | 2 +- src/condition.cpp | 4 +- src/condition.hpp | 16 +- src/parser/parser_v2.cpp | 14 +- tests/condition_test.cpp | 81 +++- tests/integration/conditions/test.cpp | 382 ++++++++++++++++++ .../conditions/yaml/global_transformer.yaml | 19 + .../conditions/yaml/input_transformer.yaml | 20 + .../yaml/overlapping_transformers.yaml | 52 +++ 9 files changed, 570 insertions(+), 20 deletions(-) create mode 100644 tests/integration/conditions/yaml/overlapping_transformers.yaml diff --git a/src/PWTransformer.cpp b/src/PWTransformer.cpp index c6bff8495..cb7090003 100644 --- a/src/PWTransformer.cpp +++ b/src/PWTransformer.cpp @@ -1403,7 +1403,7 @@ PW_TRANSFORM_ID PWTransformer::getIDForString(std::string_view str) else if (str == "keys_only") return PWT_KEYS_ONLY; else if (str == "values_only") - return PWT_KEYS_ONLY; + return PWT_VALUES_ONLY; else if (str == "unicode_normalize") return PWT_UNICODE_NORMALIZE; diff --git a/src/condition.cpp b/src/condition.cpp index 6fd33a7ee..91b49ff09 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -110,7 +110,7 @@ std::optional condition::match(const object_store &store, return std::nullopt; } - for (const auto &[target, name, key_path, transformers] : targets_) { + for (const auto &[target, name, key_path, transformers, source] : targets_) { if (deadline.expired()) { throw ddwaf::timeout_exception(); } @@ -128,7 +128,7 @@ std::optional condition::match(const object_store &store, } std::optional optional_match; - if (source_ == data_source::keys) { + if (source == data_source::keys) { object::key_iterator it(object, key_path, objects_excluded, limits_); optional_match = match_target(it, processor, transformers, deadline); } else { diff --git a/src/condition.hpp b/src/condition.hpp index 8cff98e0d..38646f091 100644 --- a/src/condition.hpp +++ b/src/condition.hpp @@ -27,20 +27,21 @@ namespace ddwaf { class condition { public: using ptr = std::shared_ptr; + + enum class data_source : uint8_t { values, keys }; + struct target_type { manifest::target_type root; std::string name; - std::vector key_path; - std::vector transformers; + std::vector key_path{}; + std::vector transformers{}; + data_source source{data_source::values}; }; - enum class data_source : uint8_t { values, keys }; - condition(std::vector targets, std::shared_ptr processor, - std::string data_id = {}, ddwaf::object_limits limits = ddwaf::object_limits(), - data_source source = data_source::values) + std::string data_id = {}, ddwaf::object_limits limits = ddwaf::object_limits()) : targets_(std::move(targets)), processor_(std::move(processor)), - data_id_(std::move(data_id)), limits_(limits), source_(source) + data_id_(std::move(data_id)), limits_(limits) {} ~condition() = default; @@ -75,7 +76,6 @@ class condition { std::shared_ptr processor_; std::string data_id_; ddwaf::object_limits limits_; - data_source source_; }; } // namespace ddwaf diff --git a/src/parser/parser_v2.cpp b/src/parser/parser_v2.cpp index c0ec08989..2a4ebc08f 100644 --- a/src/parser/parser_v2.cpp +++ b/src/parser/parser_v2.cpp @@ -124,6 +124,7 @@ std::vector parse_transformers( throw ddwaf::parsing_error("invalid transformer " + std::string(transformer)); default: transformers.push_back(transform_id); + break; } } return transformers; @@ -165,18 +166,21 @@ condition::ptr parse_rule_condition(const parameter::map &root, manifest &target target.root = target_manifest.insert(address); target.name = address; target.key_path = std::move(kp); - auto input_transformers = at(input, "transformers", {}); - if (input_transformers.empty()) { + + auto it = input.find("transformers"); + if (it == input.end()) { + target.source = source; target.transformers = transformers; } else { - target.transformers = parse_transformers(input_transformers, source); + auto input_transformers = static_cast(it->second); + target.source = condition::data_source::values; + target.transformers = parse_transformers(input_transformers, target.source); } - targets.emplace_back(target); } return std::make_shared( - std::move(targets), std::move(processor), std::move(rule_data_id), limits, source); + std::move(targets), std::move(processor), std::move(rule_data_id), limits); } rule_spec parse_rule(parameter::map &rule, manifest &target_manifest, diff --git a/tests/condition_test.cpp b/tests/condition_test.cpp index dc41a2f31..2a646d2f2 100644 --- a/tests/condition_test.cpp +++ b/tests/condition_test.cpp @@ -4,6 +4,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2021 Datadog, Inc. +#include "PWTransformer.h" #include "test.h" using namespace ddwaf; @@ -13,7 +14,7 @@ TEST(TestCondition, Match) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query"}); auto cond = std::make_shared( std::move(targets), std::make_unique(".*", 0, true)); @@ -139,12 +140,84 @@ TEST(TestCondition, MatchWithMultipleTransformers) EXPECT_TRUE(match->key_path.empty()); } +TEST(TestCondition, MatchOnKeys) +{ + std::vector targets; + + ddwaf::manifest manifest; + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}, + condition::data_source::keys}); + + auto cond = std::make_shared( + std::move(targets), std::make_unique("value", 0, true)); + + ddwaf_object root; + ddwaf_object tmp; + ddwaf_object value; + ddwaf_object_map(&value); + ddwaf_object_map_add(&value, "value", ddwaf_object_string(&tmp, "1729")); + ddwaf_object_map(&root); + ddwaf_object_map_add(&root, "server.request.query", &value); + + ddwaf::object_store store(manifest); + store.insert(root); + + ddwaf::timer deadline{2s}; + + auto match = cond->match(store, {}, true, {}, deadline); + EXPECT_TRUE(match.has_value()); + + EXPECT_STREQ(match->resolved.c_str(), "value"); + EXPECT_STREQ(match->matched.c_str(), "value"); + EXPECT_STREQ(match->operator_name.data(), "match_regex"); + EXPECT_STREQ(match->operator_value.data(), "value"); + EXPECT_STREQ(match->address.data(), "server.request.query"); + EXPECT_EQ(match->key_path.size(), 1); + EXPECT_STREQ(match->key_path[0].data(), "value"); +} + +TEST(TestCondition, MatchOnKeysWithTransformer) +{ + std::vector targets; + + ddwaf::manifest manifest; + targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, + {PWT_LOWERCASE}, condition::data_source::keys}); + + auto cond = std::make_shared( + std::move(targets), std::make_unique("value", 0, true)); + + ddwaf_object root; + ddwaf_object tmp; + ddwaf_object value; + ddwaf_object_map(&value); + ddwaf_object_map_add(&value, "VALUE", ddwaf_object_string(&tmp, "1729")); + ddwaf_object_map(&root); + ddwaf_object_map_add(&root, "server.request.query", &value); + + ddwaf::object_store store(manifest); + store.insert(root); + + ddwaf::timer deadline{2s}; + + auto match = cond->match(store, {}, true, {}, deadline); + EXPECT_TRUE(match.has_value()); + + EXPECT_STREQ(match->resolved.c_str(), "value"); + EXPECT_STREQ(match->matched.c_str(), "value"); + EXPECT_STREQ(match->operator_name.data(), "match_regex"); + EXPECT_STREQ(match->operator_value.data(), "value"); + EXPECT_STREQ(match->address.data(), "server.request.query"); + EXPECT_EQ(match->key_path.size(), 1); + EXPECT_STREQ(match->key_path[0].data(), "VALUE"); +} + TEST(TestCondition, NoMatch) { std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("http.client_ip"), "http.client_ip", {}, {}}); + targets.push_back({manifest.insert("http.client_ip"), "http.client_ip"}); auto cond = std::make_shared(std::move(targets), std::make_unique(std::vector{})); @@ -168,7 +241,7 @@ TEST(TestCondition, ExcludeInput) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query"}); auto cond = std::make_shared( std::move(targets), std::make_unique(".*", 0, true)); @@ -192,7 +265,7 @@ TEST(TestCondition, ExcludeKeyPath) std::vector targets; ddwaf::manifest manifest; - targets.push_back({manifest.insert("server.request.query"), "server.request.query", {}, {}}); + targets.push_back({manifest.insert("server.request.query"), "server.request.query"}); auto cond = std::make_shared( std::move(targets), std::make_unique(".*", 0, true)); diff --git a/tests/integration/conditions/test.cpp b/tests/integration/conditions/test.cpp index e97824818..a6b667a26 100644 --- a/tests/integration/conditions/test.cpp +++ b/tests/integration/conditions/test.cpp @@ -76,6 +76,77 @@ TEST(TestConditionsIntegration, GlobalTransformer) ddwaf_destroy(handle); } +TEST(TestConditionsIntegration, GlobalTransformerKeysOnly) +{ + auto rule = readFile("global_transformer.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "RULE3", ddwaf_object_string(&tmp, "randomvalue")); + ddwaf_object_map_add(¶meter, "value3_0", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "key", ddwaf_object_string(&tmp, "RULE3")); + ddwaf_object_map_add(¶meter, "value3_0", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "key", ddwaf_object_string(&tmp, "RULE3")); + ddwaf_object_map_add(¶meter, "value3_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "RULE3", ddwaf_object_string(&tmp, "randomvalue")); + ddwaf_object_map_add(¶meter, "value3_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} + TEST(TestConditionsIntegration, InputTransformer) { auto rule = readFile("input_transformer.yaml", base_dir); @@ -138,3 +209,314 @@ TEST(TestConditionsIntegration, InputTransformer) ddwaf_destroy(handle); } + +TEST(TestConditionsIntegration, InputTransformerKeysOnly) +{ + auto rule = readFile("input_transformer.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "RULE3", ddwaf_object_string(&tmp, "randomvalue")); + ddwaf_object_map_add(¶meter, "value3_0", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "key", ddwaf_object_string(&tmp, "RULE3")); + ddwaf_object_map_add(¶meter, "value3_0", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "key", ddwaf_object_string(&tmp, "RULE3")); + ddwaf_object_map_add(¶meter, "value3_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "RULE3", ddwaf_object_string(&tmp, "randomvalue")); + ddwaf_object_map_add(¶meter, "value3_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} + +TEST(TestConditionsIntegration, OverlappingTransformer) +{ + auto rule = readFile("overlapping_transformers.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_0", ddwaf_object_string(&tmp, " RULE1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_0", ddwaf_object_string(&tmp, " rule1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_1", ddwaf_object_string(&tmp, " rule1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_1", ddwaf_object_string(&tmp, " RULE1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_2", ddwaf_object_string(&tmp, " rule1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_2", ddwaf_object_string(&tmp, " RULE1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(¶meter, "value1_3", ddwaf_object_string(&tmp, " RULE1 ")); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} + +TEST(TestConditionsIntegration, OverlappingTransformerKeysOnly) +{ + auto rule = readFile("overlapping_transformers.yaml", base_dir); + ASSERT_TRUE(rule.type != DDWAF_OBJ_INVALID); + + ddwaf_config config{{0, 0, 0}, {nullptr, nullptr}, ddwaf_object_free}; + + ddwaf_handle handle = ddwaf_init(&rule, &config, nullptr); + ASSERT_NE(handle, nullptr); + ddwaf_object_free(&rule); + + ddwaf_object tmp; + /* {*/ + /*ddwaf_context context = ddwaf_context_init(handle);*/ + /*ASSERT_NE(context, nullptr);*/ + + /*ddwaf_object parameter = DDWAF_OBJECT_MAP;*/ + /*ddwaf_object map = DDWAF_OBJECT_MAP;*/ + /*ddwaf_object_map_add(&map, "rule2", ddwaf_object_string(&tmp, "value"));*/ + /*ddwaf_object_map_add(¶meter, "value2_0", &map);*/ + + /*EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH);*/ + + /*ddwaf_context_destroy(context);*/ + /*}*/ + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "rule2", ddwaf_object_string(&tmp, "value")); + ddwaf_object_map_add(¶meter, "value2_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "value", ddwaf_object_string(&tmp, "rule2")); + ddwaf_object_map_add(¶meter, "value2_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "value", ddwaf_object_string(&tmp, "RULE2")); + ddwaf_object_map_add(¶meter, "value2_1", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "value", ddwaf_object_string(&tmp, "RULE2")); + ddwaf_object_map_add(¶meter, "value2_2", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "rule2", ddwaf_object_string(&tmp, "value")); + ddwaf_object_map_add(¶meter, "value2_2", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "rule2", ddwaf_object_string(&tmp, "value")); + ddwaf_object_map_add(¶meter, "value2_3", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "value", ddwaf_object_string(&tmp, "rule2")); + ddwaf_object_map_add(¶meter, "value2_3", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_MATCH); + + ddwaf_context_destroy(context); + } + + { + ddwaf_context context = ddwaf_context_init(handle); + ASSERT_NE(context, nullptr); + + ddwaf_object parameter = DDWAF_OBJECT_MAP; + ddwaf_object map = DDWAF_OBJECT_MAP; + ddwaf_object_map_add(&map, "value", ddwaf_object_string(&tmp, "RULE2")); + ddwaf_object_map_add(¶meter, "value2_3", &map); + + EXPECT_EQ(ddwaf_run(context, ¶meter, nullptr, LONG_TIME), DDWAF_OK); + + ddwaf_context_destroy(context); + } + + ddwaf_destroy(handle); +} diff --git a/tests/integration/conditions/yaml/global_transformer.yaml b/tests/integration/conditions/yaml/global_transformer.yaml index 24a259378..07198813f 100644 --- a/tests/integration/conditions/yaml/global_transformer.yaml +++ b/tests/integration/conditions/yaml/global_transformer.yaml @@ -37,3 +37,22 @@ rules: - lowercase - compressWhiteSpace + - id: rule3 + name: rule3 + tags: + type: flow3 + category: category3 + confidence: 1000 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value3_0 + - address: value3_1 + regex: rule3 + options: + case_sensitive: true + transformers: + - keys_only + - lowercase + diff --git a/tests/integration/conditions/yaml/input_transformer.yaml b/tests/integration/conditions/yaml/input_transformer.yaml index d5ec77d1c..1981e0338 100644 --- a/tests/integration/conditions/yaml/input_transformer.yaml +++ b/tests/integration/conditions/yaml/input_transformer.yaml @@ -35,3 +35,23 @@ rules: regex: ^ rule2 $ options: case_sensitive: true + - id: rule3 + name: rule3 + tags: + type: flow3 + category: category3 + confidence: 1000 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value3_0 + transformers: + - keys_only + - lowercase + - address: value3_1 + transformers: + - lowercase + regex: rule3 + options: + case_sensitive: true diff --git a/tests/integration/conditions/yaml/overlapping_transformers.yaml b/tests/integration/conditions/yaml/overlapping_transformers.yaml new file mode 100644 index 000000000..642bcde4a --- /dev/null +++ b/tests/integration/conditions/yaml/overlapping_transformers.yaml @@ -0,0 +1,52 @@ +version: '2.1' +rules: + - id: rule1 + name: rule1 + tags: + type: flow1 + category: category1 + confidence: 1 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value1_0 + - address: value1_1 + transformers: [] + - address: value1_2 + transformers: + - compressWhiteSpace + - address: value1_3 + transformers: + - lowercase + - compressWhiteSpace + regex: ^ rule1 $ + options: + case_sensitive: true + transformers: + - lowercase + + - id: rule2 + name: rule2 + tags: + type: flow2 + category: category2 + confidence: 1000 + conditions: + - operator: match_regex + parameters: + inputs: + - address: value2_0 + - address: value2_1 + transformers: + - values_only + - address: value2_2 + transformers: + - lowercase + - address: value2_3 + transformers: [] + regex: rule2 + options: + case_sensitive: true + transformers: + - keys_only