Let named endpoints be exempt from the WAF hard block #6

Merged
james merged 2 commits from hard-block-exempt into main 2026-10-08 22:05:30 +00:00
Owner

Problem

CENTINELA_WAF_HARD_BLOCK cannot be turned on in production. At paranoia 3, binary request bodies score far above any attack:

Request CRS score
git-upload-pack on the git host 153, 186
Ghost ActivityPub webhook 276
PHP-CGI, Langflow and Flowise exploit attempts 64 to 83

No single threshold separates them, and CENTINELA_BYPASS_PREFIXES cannot name /<owner>/<repo>/git-upload-pack.

Change

New setting CENTINELA_WAF_HARD_BLOCK_EXEMPT: comma-separated [host]/pattern entries. Unset by default.

CENTINELA_WAF_HARD_BLOCK_EXEMPT=git.example.org/*/*/git-upload-pack,git.example.org/*/*/git-receive-pack,git.example.org/v2/*/*/blobs/uploads/*,/.ghost/activitypub/*
  • Host: matched exactly, ignoring case and port. Without one (/hooks/*) the entry applies to every host. A bare host (files.example.org) exempts all of its paths.
  • Pattern: a path.Match pattern over the whole decoded path. * stays within one path segment.
  • Scope: exempt from the hard block only. The request is still scored and still goes through the gate to the model, which can refuse it. Full bypass remains CENTINELA_BYPASS_PREFIXES.
  • A malformed pattern, or a host with a port or wildcard, fails at startup.

Tests

  • Config: parsing, host case and port, * not crossing a segment, host-less and bare-host entries, registry upload paths (opening POST and upload session), and rejection of bad entries.
  • Engine: an exempt endpoint scoring 186 reaches the model and is allowed; the same path on another host and another path on the same host are hard-blocked; an exempt request the model judges hostile is still refused.

make vet, make build and make test (race detector) pass.

Independent of #5. Merging to main runs build-and-push, which tags and publishes the next patch version.

## Problem `CENTINELA_WAF_HARD_BLOCK` cannot be turned on in production. At paranoia 3, binary request bodies score far above any attack: | Request | CRS score | |---|---| | `git-upload-pack` on the git host | 153, 186 | | Ghost ActivityPub webhook | 276 | | PHP-CGI, Langflow and Flowise exploit attempts | 64 to 83 | No single threshold separates them, and `CENTINELA_BYPASS_PREFIXES` cannot name `/<owner>/<repo>/git-upload-pack`. ## Change New setting `CENTINELA_WAF_HARD_BLOCK_EXEMPT`: comma-separated `[host]/pattern` entries. Unset by default. ``` CENTINELA_WAF_HARD_BLOCK_EXEMPT=git.example.org/*/*/git-upload-pack,git.example.org/*/*/git-receive-pack,git.example.org/v2/*/*/blobs/uploads/*,/.ghost/activitypub/* ``` - **Host:** matched exactly, ignoring case and port. Without one (`/hooks/*`) the entry applies to every host. A bare host (`files.example.org`) exempts all of its paths. - **Pattern:** a `path.Match` pattern over the whole decoded path. `*` stays within one path segment. - **Scope:** exempt from the hard block only. The request is still scored and still goes through the gate to the model, which can refuse it. Full bypass remains `CENTINELA_BYPASS_PREFIXES`. - A malformed pattern, or a host with a port or wildcard, fails at startup. ## Tests - Config: parsing, host case and port, `*` not crossing a segment, host-less and bare-host entries, registry upload paths (opening POST and upload session), and rejection of bad entries. - Engine: an exempt endpoint scoring 186 reaches the model and is allowed; the same path on another host and another path on the same host are hard-blocked; an exempt request the model judges hostile is still refused. `make vet`, `make build` and `make test` (race detector) pass. Independent of #5. Merging to `main` runs `build-and-push`, which tags and publishes the next patch version.
Let named endpoints be exempt from the WAF hard block
Some checks failed
security-scan / security-scan (pull_request) Successful in 1m39s
test / go (pull_request) Has been cancelled
a797ed0861
Binary request bodies score far above any attack under CRS at paranoia
3: in production a git-upload-pack negotiation scored 153 and 186, and
Ghost's ActivityPub webhook 276, against 64 to 83 for PHP-CGI and
Langflow exploit attempts. No single CENTINELA_WAF_HARD_BLOCK threshold
separates them, and a bypass prefix cannot name
/<owner>/<repo>/git-upload-pack.

CENTINELA_WAF_HARD_BLOCK_EXEMPT takes comma-separated [host]/pattern
entries. The host is matched exactly, ignoring case and port; without
one the entry applies to every host, and a bare host exempts all of its
paths. The pattern is a path.Match pattern over the decoded path, so *
stays within one segment.

An exempt request skips the hard block only. It is still scored and
still goes through the gate to the model, which can refuse it.

🔎 ojo scan results

Severity Count
🟠 HIGH 2
🟡 MEDIUM 4
🟢 LOW 1
Details (7)
Type Severity ID/Rule Location Description
vuln 🟠 HIGH GHSA-6gcq-wc29-5xf2 github.com/corazawaf/coraza/[email protected] Coraza JSON body processor: argument-limit truncation reopens an unbounded-depth gjson.Valid stack overflow (process crash)
vuln 🟠 HIGH CVE-2026-41510 github.com/corazawaf/coraza/[email protected] Coraza: Silent argument drop at ArgumentLimit allows bypass of ARGS-targeted rules via parameter flooding
vuln 🟡 MEDIUM GHSA-3wr7-993q-jrff github.com/corazawaf/coraza/[email protected] Coraza: Multipart filename* (RFC 5987) charset restriction lets a decoy filename bypass FILES-based rules
vuln 🟡 MEDIUM GHSA-5gj4-9gm7-2fx2 github.com/corazawaf/coraza/[email protected] Coraza body processor has a JSON key collision that allows unauthenticated attackers to bypass OWASP CRS inspection
vuln 🟡 MEDIUM GHSA-g4qm-m288-5cp9 github.com/corazawaf/coraza/[email protected] Coraza has Cookie Parser Confusion
vuln 🟡 MEDIUM GHSA-w253-m66g-rx24 github.com/corazawaf/coraza/[email protected] Coraza: URL-encoded form Content-Type parameters bypass Coraza body inspection
misconfig 🟢 LOW dockerfile-no-healthcheck Dockerfile:1 image has no HEALTHCHECK
<!-- ojo-scan-summary --> ### 🔎 ojo scan results | Severity | Count | |---|---| | 🟠 HIGH | 2 | | 🟡 MEDIUM | 4 | | 🟢 LOW | 1 | <details><summary>Details (7)</summary> | Type | Severity | ID/Rule | Location | Description | |---|---|---|---|---| | vuln | 🟠 HIGH | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-6gcq-wc29-5xf2" target="_blank" rel="noopener noreferrer">GHSA-6gcq-wc29-5xf2</a> | github.com/corazawaf/coraza/[email protected] | Coraza JSON body processor: argument-limit truncation reopens an unbounded-depth gjson.Valid stack overflow (process crash) | | vuln | 🟠 HIGH | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-6r3q-mjv7-xr8m" target="_blank" rel="noopener noreferrer">CVE-2026-41510</a> | github.com/corazawaf/coraza/[email protected] | Coraza: Silent argument drop at ArgumentLimit allows bypass of ARGS-targeted rules via parameter flooding | | vuln | 🟡 MEDIUM | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-3wr7-993q-jrff" target="_blank" rel="noopener noreferrer">GHSA-3wr7-993q-jrff</a> | github.com/corazawaf/coraza/[email protected] | Coraza: Multipart filename* (RFC 5987) charset restriction lets a decoy filename bypass FILES-based rules | | vuln | 🟡 MEDIUM | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-5gj4-9gm7-2fx2" target="_blank" rel="noopener noreferrer">GHSA-5gj4-9gm7-2fx2</a> | github.com/corazawaf/coraza/[email protected] | Coraza body processor has a JSON key collision that allows unauthenticated attackers to bypass OWASP CRS inspection | | vuln | 🟡 MEDIUM | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-g4qm-m288-5cp9" target="_blank" rel="noopener noreferrer">GHSA-g4qm-m288-5cp9</a> | github.com/corazawaf/coraza/[email protected] | Coraza has Cookie Parser Confusion | | vuln | 🟡 MEDIUM | <a href="https://github.com/corazawaf/coraza/security/advisories/GHSA-w253-m66g-rx24" target="_blank" rel="noopener noreferrer">GHSA-w253-m66g-rx24</a> | github.com/corazawaf/coraza/[email protected] | Coraza: URL-encoded form Content-Type parameters bypass Coraza body inspection | | misconfig | 🟢 LOW | dockerfile-no-healthcheck | <a href="https://git.colibrisec.org/ColibriSec/centinela/src/commit/1b75f2048a0d5410788a24d300f1c31ddb43c3c7/Dockerfile#L1" target="_blank" rel="noopener noreferrer">Dockerfile:1</a> | image has no HEALTHCHECK | </details>
Keep the hard-block exemption test clear of the end of the file
All checks were successful
security-scan / security-scan (pull_request) Successful in 25s
test / go (pull_request) Successful in 6m0s
1b75f2048a
james merged commit e588ac65ed into main 2026-10-08 22:05:30 +00:00
james deleted branch hard-block-exempt 2026-10-08 22:05:32 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ColibriSec/centinela!6
No description provided.