Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module-based rule evaluation precedence #353

Merged
merged 35 commits into from
Dec 2, 2024
Merged

Conversation

Anilm3
Copy link
Collaborator

@Anilm3 Anilm3 commented Oct 28, 2024

This PR introduces the new concept of modules to better organise rules based on their precedence. Modules are introduced as a generic mechanism which contains a set of rules in the required order (user / base, blocking, etc). Individual modules can have optional grouping, which is introduced specifically for the purpose of having independent collections within the waf module, as the short-circuit evaluation follows a different criteria due to rules being grouped by type.

The modules introduced are the following: network-acl, authentication-acl, custom-acl, configuration, business-logic, rasp, waf. The network and authentication modules do not follow the provided timeout, and the ordering of each module changes a little bit based on whether user (Custom) or base (DD) rules should take precedence.

Related Jira: APPSEC-55598

@codecov-commenter
Copy link

codecov-commenter commented Oct 28, 2024

Codecov Report

Attention: Patch coverage is 92.08333% with 19 lines in your changes missing coverage. Please review.

Project coverage is 84.95%. Comparing base (eb80490) to head (d880126).

Files with missing lines Patch % Lines
src/module.cpp 89.74% 4 Missing and 4 partials ⚠️
src/ruleset.hpp 33.33% 0 Missing and 6 partials ⚠️
src/context.hpp 33.33% 0 Missing and 2 partials ⚠️
src/rule.hpp 87.50% 0 Missing and 2 partials ⚠️
src/builder/module_builder.cpp 96.87% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #353      +/-   ##
==========================================
+ Coverage   84.68%   84.95%   +0.26%     
==========================================
  Files         153      157       +4     
  Lines        7889     7994     +105     
  Branches     3520     3551      +31     
==========================================
+ Hits         6681     6791     +110     
+ Misses        460      459       -1     
+ Partials      748      744       -4     
Flag Coverage Δ
waf_test 84.95% <92.08%> (+0.26%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@pr-commenter
Copy link

pr-commenter bot commented Oct 28, 2024

Benchmarks

Benchmark execution time: 2024-12-02 11:52:22

Comparing candidate commit d880126 in PR branch anilm3/rule-precedence with baseline commit eb80490 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 1 metrics, 0 unstable metrics.

return std::hash<std::string_view>{}(address);
}

struct target_address {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not currently used, but I plan to start using them soon.

@Anilm3 Anilm3 changed the title [WIP] Rule precedence Module-based rule evaluation precedence Nov 25, 2024
@Anilm3 Anilm3 marked this pull request as ready for review November 27, 2024 13:54
@Anilm3 Anilm3 requested a review from a team as a code owner November 27, 2024 13:54
@Leiyks Leiyks self-requested a review November 29, 2024 14:12
Copy link

@Leiyks Leiyks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

src/builder/module_builder.cpp Outdated Show resolved Hide resolved
src/builder/module_builder.hpp Outdated Show resolved Hide resolved
src/builder/module_builder.hpp Outdated Show resolved Hide resolved
src/clock.hpp Show resolved Hide resolved
src/context.hpp Outdated Show resolved Hide resolved
src/module.cpp Show resolved Hide resolved
src/rule.hpp Show resolved Hide resolved
src/rule.hpp Outdated Show resolved Hide resolved
src/ruleset.hpp Outdated Show resolved Hide resolved
@@ -22,33 +23,22 @@
namespace ddwaf {

struct ruleset {
void insert_rule(const std::shared_ptr<rule> &rule)
// OLINTNEXTLINE(bugprone-easily-swappable-parameters)
void insert_rules(const std::vector<std::shared_ptr<core_rule>> &base,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need shared ownership so that ruleset_builder can reuse the rules in updates that don't replace the rules? Did you ensure that rules that are mutated in an update (through toggle/set_actions/set_verdict) are not incorrectly shared between rulesets?

Copy link
Collaborator Author

@Anilm3 Anilm3 Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need shared ownership so that ruleset_builder can reuse the rules in updates that don't replace the rules?

Yes, and between live handles / contexts during or after update.

Did you ensure that rules that are mutated in an update (through toggle/set_actions/set_verdict) are not incorrectly shared between rulesets?

Currently rules are not mutated, they are regenerated when overrides are applied.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Does it mean the current code is buggy, given that you changed the definition of base_rule_update? I find this strategy on the dangerous side, because the correctness depends on distinct parts of the codebase to act in concert not to do unsafe writes.

Perhaps a better alternative would be to make core_rule immutable; the mutation methods would instead return a new instance. You could then perhaps even avoid recreating the full set of rules; the ruleset_builder would need to store the original rules (before overrides).

Copy link
Collaborator Author

@Anilm3 Anilm3 Nov 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it mean the current code is buggy, given that you changed the definition of base_rule_update?

Not really, the only difference is that now an update to the actions will result in regenerating rules.

I find this strategy on the dangerous side, because the correctness depends on distinct parts of the codebase to act in concert not to do unsafe writes.

Perhaps a better alternative would be to make core_rule immutable; the mutation methods would instead return a new instance. You could then perhaps even avoid recreating the full set of rules; the ruleset_builder would need to store the original rules (before overrides).

I have to refactor everything for the multi-configuration builder, I am making rules safely mutable to avoid the re-computation costs the current strategy results in, or at least this is the direction I'm currently going on, I might change my mind.

@Anilm3 Anilm3 merged commit 94a594d into master Dec 2, 2024
52 checks passed
@Anilm3 Anilm3 deleted the anilm3/rule-precedence branch December 2, 2024 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants