-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: clean matched vars after chained and non-chained rule #3418
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
Open
airween
wants to merge
2
commits into
owasp-modsecurity:v3/master
Choose a base branch
from
airween:v3/matchedvarsfix
base: v3/master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this check? If I understand correctly,
m_ruleId == 0
would be an invalid rule (caught exception). Would we even get here then? As far as I can tell, nothing bad would happen ifm_ruleId == 0
, sincecleanMatchedVars()
operates on the transaction only.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, except if it's a chained rule. Generally, every chained rule (rules?) has (have?) only one unique
id
. In libmodsecurity3, despite you set up theid
action at the first rule (in a chained rule), the last rule will own thatid
. Therefore this condition (m_ruleId > 0
) tells us this is the end of a rule, no matter that's chained or not, we should clean theMATCHED_*
variables.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. From the code (and the comment) it seems like the condition is redundant though, since
end_exec:
will always be evaluated for the last rule. So I still don't see why the extra condition is necessary.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we need to clear
MATCHED_*
variables only if the rule is a standalone rule (not chained), or it's the last part of a chained rule.This means if the rule is part if a chained rule, but not the last, then we don't clean these group of variables.
If you see the diff, we can say this solves the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand, and that's exactly what I'm saying... this will only be true when all chained rules have been processed. This will only be true when the rule is not chained. In all cases,
end_exec
will only be evaluated when the last rule has been reached, whether it's the last in a chain or a single rule. Hence:end_exec
is equivalent tom_ruleId > 0
. Unless I still don't get it...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me approach it from a different direction: if that condition were not there, the
MATCHED_*
variables would be deleted after each rule was evaulated. Not just after standalone rules, but in case of every part in chained rules. For eg. take a look at the initial rule in original issue:and the request:
If the condition were not there, then the first part of chained rule matches,
MATCHED_*
variables are set, but the engine clears them immediately after the end of processing, therefore the second part of the chained rule wont match, becauseMATCHED_VARS_NAMES
is empty.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 cents:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I worked on this fix I made several tests, this is why I could make this patch 😃.
Btw I try to figure out how can I solve the issue with your idea (clear vars before the evaluation). (As I remember I tried to go on this way, but I rejected for some reason... Let me check again.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I think I know why did I reject that solution.
Let's approach the issue from the transaction's direction. Transaction object calls the
evaluate()
function here, for eg. (there are several other call, in each phases).The
evaluate()
is part of transaction'sm_rules
member, which is a RuleSet type, see here.m_rules->evaluate()
has two arguments: phase and transaction.It grabs the rules in phase that called, see here, and iterates through them. There is an
auto
cast here, but the rule which created here can be a RuleWithActions or RuleWithOperator.But only the
RuleWithOperator
has cleanMatchedVars.I didn't want to touch this, therefore I tried to find a solution at the end of the rule processing. But we can find a different solution, eg. we can move the
cleanMatchedVars()
to another class. Then I think we can make clean method easier.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation @airween. I still don't understand why the condition is necessary, but your tests prove that the code works, so that's good enough for me. I suggest you add a comment before the condition that explains what the condition is for. Then I'll be happy.