owasp-modsecurity / owasp-modsecurity/ModSecurity

Feature Request: Wildcard/pattern support in ctl:ruleRemoveTargetById (v3)

Open
#3,505 7 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

3.x
Dominant language
C++
Stars
9.8k
Forks
1.8k
Avg merge
2h 46m
Merged PRs (30d)
1

Description

Hi team! This is my first ask/contribution to ModSecurity. I'm hoping to help improve false positive management for folks using CRS — please let me know if I can clarify anything or adjust this proposal.

Is your feature request related to a problem? Please describe.

Currently, ctl:ruleRemoveTargetById only allows excluding a Core Rule Set (CRS) rule from inspecting a literal, exact variable name (e.g., ARGS:json.JobDescription). It does not support wildcards or regular expressions.

This creates a significant pain point for modern APIs accepting JSON arrays or GraphQL payloads, where keys are dynamic:

  • Payload: [{"JobDescription": "..."}, {"JobDescription": "..."}, ...]
  • Variables: ARGS:json.0.JobDescription, ARGS:json.1.JobDescription, …

Excluding these requires listing every possible index, which is impractical and leads to users disabling rules entirely or losing protection for the whole endpoint via path exclusions.

Note: This request is related to the legacy v2 PR #3121 and Issue #911, but focuses specifically on a v3 implementation.

Describe the solution you'd like

Extend ctl:ruleRemoveTargetById to accept a pattern (regex) that matches variable names, mirroring the existing regex support in SecRuleUpdateTargetById, but enabling runtime/URI-scoped use.

Example Syntax:

SecRule REQUEST_URI "@beginsWith /api/jobs" \
    "id:100100,phase:1,pass,nolog,ctl:ruleRemoveTargetById=932125;ARGS:/^json\.\d+\.JobDescription$/"

Expected Behavior: When the target rule inspects variables, any variable whose name matches the compiled pattern is excluded. Literal targets must continue to work unchanged. Invalid regex should fail at config load.

Describe alternatives you've considered

  1. Path/method exclusion: Loses protection for the entire endpoint.
  2. SecRuleUpdateTargetById: Applies globally at configure-time, which is risky if other endpoints share the same JSON structure.

Technical Feasibility & Security Considerations (v3)

The change is feasible in v3 with localized edits, as the engine already utilizes Utils::Regex (PCRE2) for variable matching.

  • src/actions/ctl/rule_remove_target_by_id.cc: In init(), detect the COLLECTION:/.../ pattern. If it's a regex, compile via Utils::Regex and push to the transaction state.
  • src/rule_with_operator.cc: In getFinalVars and the evaluate loop, check exclusions against regex targets using m_regex->searchAll(varName).size() > 0.

ReDoS Mitigations Risks:
Because the variable name (e.g., JSON key) is user-controlled, strict limits are required to prevent ReDoS via the ctl evaluation:

  1. Subject Length Limit: Cap the evaluated string (variable name) at 256 characters. If exceeded, skip the regex match (fail closed/evaluate the rule).
  2. Match Limits: Utilize pcre2_set_match_limit() for this specific code path.
  3. Compile-time validation: Reject known ReDoS patterns at config load.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading src/actions/ctl/rule_remove_target_by_id.cc and src/rule_with_operator.cc, focusing on init(), getFinalVars, and the evaluation loop. Check how Utils::Regex is used and how transaction state stores exclusions. Done means literal targets still work, valid patterns match variable names at runtime, invalid regex fails during configuration, and the stated ReDoS limits are addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.