Skip to content

Instantly share code, notes, and snippets.

@M4tteoP
Last active April 12, 2023 09:32
Show Gist options
  • Save M4tteoP/57001a5066f2f76c9f99c6dc3e9bf4af to your computer and use it in GitHub Desktop.
Save M4tteoP/57001a5066f2f76c9f99c6dc3e9bf4af to your computer and use it in GitHub Desktop.
Coraza experimental MultiPhase evaluation reasonings and current status

Multiphase PRs and implementations

  1. corazawaf/coraza#565: Initial PR with reasoning about the feature and multiphase evaluation implementation for not chaines rules.
  2. corazawaf/coraza#692: Chained rules support.
  3. corazawaf/coraza#719: on top of #692, extends coverage, splits ARGS and ARGS_NAMES into *_GET and *_POST variables at parsing time.

Open Problems that may lead to CRS bypasses or false positives

Overall many CRS chains are marked at phase:1 or obligatorily require the phase:2 because of rules targetting single variables such as request body. Note: #719 PR proposes to let possible to evaluate the same variable in more then one phase if part of a chain. I think that it is:

  • needed because otherwise chains anticipated may not be able to work anymore at the next phase. In the following example, if REQUEST_URI is skipped at phase 2 because already tried to match at phase 1, the first rule will not match at phase:2, therefore REQUEST_BODY will never work.
SecRule REQUEST_URI "/chain_phase2" "id:10, phase:2, t:none, log, setvar:'tx.set1=1', chain"
	SecRule REQUEST_URI| REQUEST_BODY "chain_phase2" "setvar:'tx.set2=2'"
  • doable because anomaly scores increments only happen at the most inner rule, therefore when all the previous matched

MovingIntoAllowedPhase: A variable is anticipated to a phase in which an allow action is triggered. The variable is not evaluated in the inferred phase, NOR in its initial phase (not being anymore its minimal phase).

Examples (allow.go):

  • See rules 45 and 46. Rule 45 allows all the request phases (1 and 2) Rule 46 is anticipated to phase 1, therefore it is skipped. When phase 3 is evaluated, rule 46 is skipped because it is not anymore in its minPhase.
  • It applies also to rules 31-42 and 11-22.

Possible solutions: Find a way to be sure that each variable has been already evaluated in an inferred phase or not. If this is not the case, we have to evaluate in another phase up to its initial one. We have to consider at least two cases:

  • The rule anticipated has been evaluated in the inferred phase before an allow action happend (it is okay do not evaluate afterwards)
  • The rule anticipated has not been evaluated because of an allow action. We have to try to evaluate it in other inferred phases)
  1. Add booleans for each variable to keeep tracking if they have been evaluated. It comes with overhead.
  2. Keep track of the allowed phases and evaluate the variables that have the minPhase skipped. It may lead to double evaluation (see point 1)

🆘 MovingAllowingRules: Moving rules with allow actions leads to unwanted skipped rules (and allowed requests). The allow action is executed at the wrong phase.

Examples (allow.go):

  • See rules 70 and 71. Rule 71, being anticipated at phase:1, is evaluated before rule 70. The latter should have denied the request at phase:2

Possible solutions:

  1. Rules with allow actions should not have inferred phases (only the provided one)
  2. Evaluate the rule, but wait until the right phase is reached for enforcing the allow action. Problems can arise because of rules ordering. E.g. a phase 3 with "allow", anticipated at phase:1 could delay the allow action when phase:3 is reached, but the rules order is not respected. Maybe other phase 3 rules should have been evaluated before the allow action.

🆘 Skip actions and RemoveBy actions Similar to MovingAllowingRules, being actions that alter the phase in which they are triggered, anticipating them can lead to wrong flows. Possible solution: do not permit to anticipate rules with Skip and SkipAfter. It also would permit to be safe with rules with multiple targets and relative actions that I think would be executed twice.

SideNotes

Expecially thinking about chain evaluation with multiphase, a structure able to map the statues (matched/not matched) of each rule and variable might provide a new way to handle it. But it would require a significat design/refactor and overhead for keeping, updating and cleaning the statuses of each rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment