coreruleset / coreruleset/coreruleset

RFC: CRS Access Control Dimensions - Design Exploration

Open
#4,615 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

:bulb: ideas
Dominant language
Python
Stars
3.3k
Forks
470
Avg merge
1d 20h
Merged PRs (30d)
11

Description

Current decision model

Today CRS has essentially a 2D model:

Dimension Controls Values
Paranoia Level which rules are active (detection breadth) PL1–PL4
Severity how much each match contributes (score weight) CRITICAL=5, ERROR=4, WARNING=3, NOTICE=2

These feed into a single aggregate anomaly score compared against a single threshold. It's a flat sum - every match is fungible.

Unused data already in the rules

CRS already tracks rich metadata that is logged but never used for decisions:

1. Attack category scores (8 categories, all wasted)

tx.sql_injection_score, tx.xss_score, tx.rfi_score, tx.lfi_score, tx.rce_score, tx.php_injection_score, tx.http_violation_score, tx.session_fixation_score

These are accumulated per-request and reported in rule 980170, but never compared to any threshold. This is the lowest-hanging fruit — we could add per-category thresholds:

tx.rce_score_threshold=5      # zero tolerance for RCE
tx.http_violation_score_threshold=15  # lenient on protocol noise

This lets operators say "block immediately on any RCE signal, but tolerate a few HTTP violations." The data pipeline already exists — we just need the decision point.

2. Platform / language tags (24 platforms, 10 languages)

Every rule is tagged with things like platform-mysql, language-java, platform-windows. But there's no mechanism to say "my stack is Java on Linux with PostgreSQL" and have CRS weight rules accordingly.

This could manifest as a platform profile — not disabling rules (which loses detection), but adjusting score contribution:

  • rules matching your stack -> full weight
  • rules targeting other platforms -> reduced weight or detection-only
3. CAPEC tags (32 unique attack patterns)

These provide a richer attack taxonomy than the 8 category scores. They could enable more granular policy, though the complexity may not be worth it for most deployments.

New dimensions worth considering

4. Confidence (doesn't exist yet, highest value)

This is the biggest gap. Today, severity measures impact (how bad is this attack if real), but nothing measures how likely the match is a true positive. Consider:

  • Rule matching UNION SELECT FROM in a query parameter -> high confidence
  • Rule matching or in a cookie value -> low confidence
  • Rule matching ../../../etc/passwd -> high confidence
  • Rule matching a 3-char SQL keyword in a Base64 blob -> low confidence

A confidence tag would let CRS weight matches differently:

high confidence + critical severity → 5 points (as today)
low confidence + critical severity → 2 points (reduced)

This directly addresses the core CRS tension: PL2+ rules exist because they catch real attacks, but they're noisy. Confidence separates "this rule is aggressive" (PL) from "this particular match is suspicious" (confidence). Rules at PL2 could carry a confidence:low tag, and the scoring engine could discount them rather than the current all-or-nothing PL gate.

5. Match location weighting

Where a pattern matched matters. SQLi in ARGS:username is more suspicious than SQLi-like patterns in REQUEST_HEADERS:Referer (which often contains legitimate URLs with SQL-like tokens). Today all variables contribute equally.

This could be a per-variable weight multiplier:

ARGS-> 1.0x (full weight)
REQUEST_HEADERS:Referer -> 0.5x
REQUEST_COOKIES -> 0.7x
6. Request context

HTTP method + content type + endpoint pattern define a request's risk profile. A POST /api/admin/query with application/json is a very different context than GET /images/logo.png. This is hard to generalize but could work as operator-defined profiles.

What I'd prioritize

Priority Dimension Effort Impact
1 Per-category thresholds Low (data exists) High - granular blocking policy
2 Confidence Medium (needs rule tagging) Very high — fundamentally improves scoring
3 Platform profile Medium (tags exist) Medium — reduces noise for known stacks
4 Match location weight High (engine changes) Medium — address FP hotspots

Per-category thresholds could be a first move — the infrastructure already exists, it's just the decision logic in REQUEST-949 that needs to check tx.*_score variables against configurable thresholds. Confidence is the most transformative but requires a project-wide effort to tag every rule.

Contributor guide

Open the contributing guide

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 with the decision logic in REQUEST-949 and the existing category-score reporting in rule 980170. Trace how the tx.*_score variables are accumulated and identify the scope of the proposed dimensions. Done requires a settled design and implementation boundary, since the issue currently presents several alternatives rather than one defined change.

Written by the indexing model from the issue text.

Assessment

Domain
security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.