Skip to content

Commit

Permalink
Short-circuit modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Anilm3 committed Nov 23, 2024
1 parent 472c898 commit 74980d0
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
7 changes: 6 additions & 1 deletion src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
#include "exception.hpp"
#include "exclusion/common.hpp"
#include "log.hpp"
#include "module.hpp"
#include "object_store.hpp"
#include "processor/base.hpp"
#include "rule.hpp"
#include "target_address.hpp"
#include "utils.hpp"

Expand Down Expand Up @@ -239,7 +241,10 @@ std::vector<event> context::eval_rules(
for (std::size_t i = 0; i < ruleset_->rule_modules.size(); ++i) {
const auto &mod = ruleset_->rule_modules[i];
auto &cache = rule_module_cache_[i];
mod.eval(events, store_, cache, policy, ruleset_->rule_matchers, deadline);
auto verdict = mod.eval(events, store_, cache, policy, ruleset_->rule_matchers, deadline);
if (verdict == rule_module::verdict_type::block) {
break;
}
}

return events;
Expand Down
2 changes: 1 addition & 1 deletion src/exclusion/rule_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class rule_filter {
std::shared_ptr<expression> expr_;
std::unordered_set<core_rule *> rule_targets_;
filter_mode mode_;
std::string action_{};
std::string action_;
};

} // namespace ddwaf::exclusion
44 changes: 29 additions & 15 deletions src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@
namespace ddwaf {

namespace {
std::optional<event> eval_rule(const core_rule &rule, const object_store &store,
core_rule::cache_type &cache, const exclusion::context_policy &policy,
using verdict_type = rule_module::verdict_type;

std::pair<std::optional<event>, verdict_type> eval_rule(const core_rule &rule,
const object_store &store, core_rule::cache_type &cache,
const exclusion::context_policy &policy,
const std::unordered_map<std::string, std::shared_ptr<matcher::base>> &dynamic_matchers,
ddwaf::timer &deadline)
{
const auto &id = rule.get_id();
auto verdict = rule.get_verdict();

if (deadline.expired()) {
DDWAF_INFO("Ran out of time while evaluating rule '{}'", id);
Expand All @@ -40,21 +44,23 @@ std::optional<event> eval_rule(const core_rule &rule, const object_store &store,

if (!rule.is_enabled()) {
DDWAF_DEBUG("Rule '{}' is disabled", id);
return std::nullopt;
return {std::nullopt, verdict_type::none};
}

std::string_view action_override;
auto exclusion = policy.find(&rule);
if (exclusion.mode == exclusion::filter_mode::bypass) {
DDWAF_DEBUG("Bypassing rule '{}'", id);
return std::nullopt;
return {std::nullopt, verdict_type::none};
}

if (exclusion.mode == exclusion::filter_mode::monitor) {
DDWAF_DEBUG("Monitoring rule '{}'", id);
action_override = "monitor";
verdict = verdict_type::monitor;
DDWAF_DEBUG("Monitoring rule '{}'", id);
} else if (exclusion.mode == exclusion::filter_mode::custom) {
action_override = exclusion.action_override;
verdict = verdict_type::block;
DDWAF_DEBUG("Evaluating rule '{}' with custom action '{}'", id, action_override);
} else {
DDWAF_DEBUG("Evaluating rule '{}'", id);
Expand All @@ -68,22 +74,23 @@ std::optional<event> eval_rule(const core_rule &rule, const object_store &store,
event->action_override = action_override;
}

return event;
return {event, verdict};
} catch (const ddwaf::timeout_exception &) {
DDWAF_INFO("Ran out of time while evaluating rule '{}'", id);
throw;
}

return std::nullopt;
return {std::nullopt, verdict_type::none};
}

} // namespace

void rule_module::eval_with_collections(std::vector<event> &events, object_store &store,
verdict_type rule_module::eval_with_collections(std::vector<event> &events, object_store &store,
cache_type &cache, const exclusion::context_policy &exclusion,
const std::unordered_map<std::string, std::shared_ptr<matcher::base>> &dynamic_matchers,
ddwaf::timer &deadline) const
{
verdict_type final_verdict = verdict_type::none;
for (const auto &collection : collections_) {
DDWAF_DEBUG("Evaluating collection: {}", collection.name);
auto &collection_cache = cache.collections[collection.name];
Expand All @@ -101,21 +108,26 @@ void rule_module::eval_with_collections(std::vector<event> &events, object_store

for (std::size_t i = collection.begin; i < collection.end; ++i) {
auto &rule = *rules_[i];
auto event =
auto [event, verdict] =
eval_rule(rule, store, cache.rules[i], exclusion, dynamic_matchers, deadline);
if (event.has_value()) {
collection_cache.type = rule.get_verdict();
collection_cache.type = verdict;
collection_cache.ephemeral = event->ephemeral;

events.emplace_back(std::move(*event));
DDWAF_DEBUG("Found event on rule {}", rule.get_id());

if (verdict > final_verdict) {
final_verdict = verdict;
}
break;
}
}
}
return final_verdict;
}

void rule_module::eval(std::vector<event> &events, object_store &store, cache_type &cache,
verdict_type rule_module::eval(std::vector<event> &events, object_store &store, cache_type &cache,
const exclusion::context_policy &exclusion,
const std::unordered_map<std::string, std::shared_ptr<matcher::base>> &dynamic_matchers,
ddwaf::timer &deadline) const
Expand All @@ -125,15 +137,17 @@ void rule_module::eval(std::vector<event> &events, object_store &store, cache_ty
const auto &rule = *rules_[i];
auto &rule_cache = cache.rules[i];

auto event = eval_rule(rule, store, rule_cache, exclusion, dynamic_matchers, deadline);
auto [event, verdict] =
eval_rule(rule, store, rule_cache, exclusion, dynamic_matchers, deadline);
if (event.has_value()) {
events.emplace_back(std::move(*event));
DDWAF_DEBUG("Found event on rule {}", rule.get_id());
break;
return verdict;
}
}
} else {
eval_with_collections(events, store, cache, exclusion, dynamic_matchers, deadline);
return verdict_type::none;
}

return eval_with_collections(events, store, cache, exclusion, dynamic_matchers, deadline);
}
} // namespace ddwaf
6 changes: 3 additions & 3 deletions src/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ class rule_module {
cache.collections.reserve(collections_.size());
}

void eval(std::vector<event> &events, object_store &store, cache_type &cache,
verdict_type eval(std::vector<event> &events, object_store &store, cache_type &cache,
const exclusion::context_policy &exclusion,
const std::unordered_map<std::string, std::shared_ptr<matcher::base>> &dynamic_matchers,
ddwaf::timer &deadline) const;

protected:
void eval_with_collections(std::vector<event> &events, object_store &store, cache_type &cache,
const exclusion::context_policy &exclusion,
verdict_type eval_with_collections(std::vector<event> &events, object_store &store,
cache_type &cache, const exclusion::context_policy &exclusion,
const std::unordered_map<std::string, std::shared_ptr<matcher::base>> &dynamic_matchers,
ddwaf::timer &deadline) const;

Expand Down

0 comments on commit 74980d0

Please sign in to comment.