Coraza: Native audit-log format allows CRLF injection and log forgery via request body and header fields
CVSS Skor
5.8
EPSS İhtimal
—
Risk Skoru
0.6
Yayın
5 gün önce
Resmî kaynaklarda yeterli kanıt bulunamadı. Bu sonuç “yama yok” anlamına gelmez.
Envanterimdeki Etkisi
Yalnızca hesabınıza eklediğiniz kişisel ürünler değerlendirilir; kurumsal envanter burada görünmez.
Oturum kontrol ediliyor…
Zafiyet Açıklaması
DayBreach CVE AI Araştırması
CVE-2026-41504 için toplanan üretici, dağıtım, yama ve güvenlik kaynağı kayıtlarını karşılaştırıp kanıt bağlantılı bir açıklama hazırlayalım.
## Root Cause File: `internal/auditlog/formats.go` — multiple sites write attacker-influenced bytes into the Native audit-log stream without escaping `\r` or `\n`: ```go // Part B — request headers (lines 72–80) for k, vv := range al.Transaction().Request().Headers() { for _, v := range vv { res.WriteByte('\n') res.WriteString(k) res.WriteString(": ") res.WriteString(v) // ← raw } } // Part C — request body (lines 85–86) if body := al.Transaction().Request().Body(); body != "" { res.WriteString(body) // ← raw res.WriteByte('\n') } // Part E — response body (lines 93–94) raw // Part F — response headers (lines 111–118) raw // Part H — error messages (line 125) raw // Part K — matched-rule raw data (line 151) raw ``` The Native format's section structure is line-based: sections are delimited by lines of the form `--<10-char-random-prefix>-<Part>--`, and line-based log parsers / SIEM rules rely on that structure. Any attacker-controlled bytes containing `\n` break the structural invariant and allow the attacker to inject lines that look like genuine audit content. The other two Native-format implementations in Coraza are not affected: the JSON formatter (`formats_json.go`) and the OCSF formatter both round-trip values through `json.Marshal`, which escapes `\r` and `\n`. ## Impact An attacker who can land bytes into any of the listed audit-log fields can inject arbitrary lines — including lines that visually resemble new log entries — into the audit log file of a defender running the default `SecAuditLogFormat Native` configuration. Realistic consequences: - **Forging entries to shift attribution.** An injected line such as `[client "9.9.9.9"] Coraza: Warning. ...` sits alongside genuine matches in Part H, and a human operator (or simple SIEM rule) reading the log cannot tell them apart. - **Confusing SIEM correlation.** Any ingestion pipeline that splits on `--...-[A-Z]--` boundaries or on `[client "..."]` patterns without validating the session prefix will treat the forged lines as separate records. - **Breaking log-parsing tooling.** Grep/awk pipelines, log tailers, and log-rotation tools with line-based assumptions can be poisoned with crafted binary sequences. - **Hiding genuine incidents.** An attacker who can also trigger a rule match on the same transaction (trivial — send any request that matches *any* audit-logged rule) can bury the real match under noise they control. The forged lines cannot trivially impersonate an entire *separate* session: the 10-char random prefix in the real boundaries (`boundaryPrefix := "--" + utils.RandomString(10) + "-"`, line 42) is not predictable from outside, and each transaction uses a fresh prefix. But the integrity of a *single* record is fully compromised, which is enough for the SIEM-confusion and attribution-shifting attacks. ## Proof of Concept Server with `coraza.conf-recommended`-style defaults: ```conf SecRuleEngine On SecAuditEngine On SecAuditLogParts ABCFHZ SecAuditLogType Serial SecAuditLog /tmp/audit.log SecAuditLogFormat Native SecRequestBodyAccess On SecRule REQUEST_METHOD "@rx ." \ "id:1001,phase:1,pass,log,auditlog,msg:'trigger'" ``` ### Body vector — reachable via stock `coraza/v3/http` + `net/http` Send an ordinary urlencoded POST whose body contains raw CRLF sequences and forged boundaries: ``` POST / HTTP/1.1 Content-Type: application/x-www-form-urlencoded evil=benign\r\n--coraza-forged-X--\r\nForgedLine: yes\r\n--coraza-forged-H--\r\n[client "9.9.9.9"] FAKE ATTACK ENTRY ``` Resulting audit.log: ``` --heLNtylvjY-C-- evil=benign --coraza-forged-X-- ForgedLine: yes --coraza-forged-H-- [client "9.9.9.9"] FAKE ATTACK ENTRY --heLNtylvjY-F-- ``` The forged `--coraza-forged-X--` / `--coraza-forged-H--` boundaries and the spoofed `[client "9.9.9.9"]` line are structurally indistinguishable from the surrounding genuine log content. No rule fires, no error is raised, the attack is invisible to the WAF. ### Header vector — reachable via non-net/http integrations only The same effect applies to Part B (request headers) and Part F (response headers) when a header value contains raw `\r\n`. Go's `net/http` rejects such headers at parse time (`400 Bad Request`), so the stock HTTP wrapper is safe from this path; the vector is reachable when Coraza is called with header values that were not validated by `net/http`: - `coraza-spoa` (HAProxy SPOP agent) forwards headers from HAProxy, which has more permissive validation. - `coraza-proxy-wasm` / Envoy WASM hosts forward header values from the upstream proxy. - Custom FFI/WASM hosts and any embedder calling `tx.AddRequestHeader(k, v)` with unvalidated bytes. Other raw-write sites (Part E response body, Part H error messages, Part K matched-rule data) share the same class of issue and should be fixed together. ## Mitigation Escape `\r` and `\n` at every raw-write site in `internal/auditlog/formats.go`. A single package-level helper is sufficient: ```go var logEscaper = strings.NewReplacer("\r", "\\r", "\n", "\\n") // Part B — header values: res.WriteString(logEscaper.Replace(v)) // Part F — header values: same // Part H — error messages: res.WriteString(logEscaper.Replace(alWithErrMsg.ErrorMessage())) // Part K — matched-rule raw data: res.WriteString(logEscaper.Replace(alEntry.Data().Raw())) ``` For Part C / Part E (bodies), the choice is policy-dependent: - **Escape inline** (`logEscaper.Replace(body)`): keeps the log human-readable for text bodies but loses fidelity for binary. - **Base64 / hex-encode** the whole part: binary-safe, matches the spirit of ModSecurity v2's binary-log handling, but less human-readable. Escaping is the minimum; base64 for bodies is the more conservative default and is a reasonable audit-log-default change. ### Additional defensive measure Consider lengthening the `boundaryPrefix` random suffix from 10 chars to ≥16 chars (line 42). This strictly raises the bar for attackers attempting to *fully* forge a separate-looking session (not just inject lines into the current one). Low-cost change; narrows future variants of this bug class. ## Affected versions The Native formatter has been present since `v3.0.0` (file existed at the first-release commit). All releases `>= 3.0.0, <= 3.7.0` are affected when `SecAuditLogFormat Native` is used with `SecAuditLogType Serial` or `SecAuditLogType Concurrent`. **Unaffected:** - Deployments using `SecAuditLogFormat JSON` (`formats_json.go` uses `json.Marshal` which escapes `\r\n`). - Deployments using OCSF output. - Deployments with `SecAuditEngine Off`. ## References - `internal/auditlog/formats.go` lines 42, 72–80 (Part B), 85–88 (Part C), 93–96 (Part E), 111–118 (Part F), 125 (Part H), 151 (Part K) - `coraza.conf-recommended` — default `SecAuditLogFormat Native`, `SecAuditLogParts ABIJDEFHZ` / `ABCFHZ` variants - CWE-117 — Improper Output Neutralization for Logs - CWE-93 — CRLF Injection
IMPACT — Etkilenen Ürünler ve Yazılımlar
Affected Products
The following products are affected by CVE-2026-41504 vulnerability. Even if our threat engine is aware of the exact versions of the products that are affected, the information is represented below.
| ID | VENDOR | PRODUCT | ACTION |
|---|---|---|---|
| 1 | go | github.com/corazawaf/coraza/v3 | İncele |
RED HAT CSAF/VEX — Ürün Etki Kontrolü
SCORING — CVSS Çoklu Kaynak Skoru
CVSS Scores
The Common Vulnerability Scoring System is a standardized framework for assessing the severity of vulnerabilities in software and systems. We collect and display CVSS scores from various sources for each CVE.
| SCORE | VERSION | SEVERITY | VECTOR | SOURCE |
|---|---|---|---|---|
| 5.8 | CVSS 3.x | — | Vektör yayımlanmadı | GitHub Advisory |
| 0.0 | CVSS 4.0 | — | Vektör yayımlanmadı | GitHub Advisory |
Yama ve İyileştirme Rehberi (Solution)
Solution & Remediation Advisory
İncelenen resmî kaynaklarda yama durumu doğrulanamadı. Bu sonuç “yama yok” anlamına gelmez.
Public exploit ve aktif sömürü durumu
Doğrulanmış exploit istihbaratı
Bu CVE için henüz doğrulanmış public PoC, exploit repository’si veya Metasploit modülü bulunamadı.
Zafiyet Dağılımı ve Saldırı Kalıpları (CWE & CAPEC)
CWE - Common Weakness Enumeration
While CVE identifies specific instances of vulnerabilities, CWE categorizes the common flaws or weaknesses that can lead to vulnerabilities. CVE-2026-41504 is associated with the following CWEs:
Common Attack Pattern Enumeration and Classification (CAPEC)
Common Attack Pattern Enumeration and Classification (CAPEC) stores attack patterns, which are descriptions of the common attributes and approaches employed by adversaries to exploit the CVE-2026-41504 weaknesses.
Saldırı Vektörü ve Erişilebilirlik Karakteristiği
Resmi Kaynaklar ve Danışma Bültenleri
İlgili Benzer Açıklar
Code injection in Gitea
gitea-runner: workflow container.options passes host namespaces and capability flags to job container when privileged mode is disabled
CVE-2026-76819
Identrail Cross-tenant IDOR: Client-supplied GitHub App installation_id is bound to the caller's workspace without ownership verification
Joker linter executed project-local .jokerd/linter.* files during linting
Coraza: Silent argument drop at ArgumentLimit allows bypass of ARGS-targeted rules via parameter flooding
Bu açığı API ile alın
Etkilenen ürünler, sürüm aralıkları, istismar durumu ve yama bilgisi tek istekte; ücretsiz anahtarla.
curl -H "x-api-key: $DAYBREACH_API_KEY" \ "https://api.enginteksut.com.tr/api/v1/intel/cves/CVE-2026-41504"