{"id":"GHSA-cqxr-jxr2-85pq","revision":null,"records":[{"revision":"4a1999d101b54fbda92e160a77689beb","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-59168","aliases":[],"title":"Dasel: Unbounded recursion in JSON and XML readers causes unrecoverable stack-overflow DoS","description":"Dasel is a command-line tool and library for querying, modifying, and transforming data structures. From 3.0.0 until 3.11.1, parsing/json/json_reader.go decodeValue, decodeObject, and decodeArray, and parsing/xml/reader.go parseElement, recurse once per input nesting level without a depth guard. Deeply nested attacker-controlled JSON or XML supplied through parsing.Format(...).NewReader(...).Read(data), the command-line interface, or the parse selector function can exhaust the Go goroutine stack and raise an unrecoverable fatal error that terminates the entire process. The XML input-size limit does not prevent depth exhaustion, and defer or recover cannot intercept the failure. This issue is fixed in version 3.11.1.","state":0,"publishedAt":"2026-09-21T16:55:07.859+00:00","modifiedAt":"2026-09-21T20:45:17.805+00:00","affected":[{"ecosystem":"Vendor product","name":"dasel","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"TomWright\",\n                    \"product\": \"dasel\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 3.0.0, < 3.11.1\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":6.2,"severity":"MEDIUM"}],"references":["https://github.com/TomWright/dasel/security/advisories/GHSA-cqxr-jxr2-85pq","https://github.com/TomWright/dasel/commit/4c91d0d02dc59ce8404709b1bfed7a6fabe62f68","https://github.com/TomWright/dasel/releases/tag/v3.11.1"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-59168","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-59168","identifiers":["CVE-2026-59168"]},"retained":false,"historicalAffected":[]},{"revision":"98349533276c46478710848c8fbb249c","observedAt":"2026-11-11T15:01:04.656+00:00","statement":{"source":"euvd","id":"EUVD-2026-84017","aliases":["CVE-2026-59168","GHSA-cqxr-jxr2-85pq"],"title":"Dasel is a command-line tool and library for querying, modifying, and transforming data structures. From 3.0.0 until 3.11.1, parsing/json/json_reader.go decodeValue, decodeObject, and decodeArray, and parsing/xml/reader.go parseElement, rec…","description":"Dasel is a command-line tool and library for querying, modifying, and transforming data structures. From 3.0.0 until 3.11.1, parsing/json/json_reader.go decodeValue, decodeObject, and decodeArray, and parsing/xml/reader.go parseElement, recurse once per input nesting level without a depth guard. Deeply nested attacker-controlled JSON or XML supplied through parsing.Format(...).NewReader(...).Read(data), the command-line interface, or the parse selector function can exhaust the Go goroutine stack and raise an unrecoverable fatal error that terminates the entire process. The XML input-size limit does not prevent depth exhaustion, and defer or recover cannot intercept the failure. This issue is fixed in version 3.11.1.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":6.2,"severity":null}],"references":["https://github.com/TomWright/dasel/security/advisories/GHSA-cqxr-jxr2-85pq","https://github.com/TomWright/dasel/commit/4c91d0d02dc59ce8404709b1bfed7a6fabe62f68","https://github.com/TomWright/dasel/releases/tag/v3.11.1"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-84017","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 21, 2026, 4:55:07 PM","dateUpdated":"Sep 21, 2026, 8:45:17 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-84017","identifiers":["EUVD-2026-84017","CVE-2026-59168","GHSA-cqxr-jxr2-85pq"]},"retained":false,"historicalAffected":[]},{"revision":"0e855c7e2dc54ffa9b37c7b9c5ce37c8","observedAt":"2026-10-25T14:19:16.843+00:00","statement":{"source":"nvd","id":"CVE-2026-59168","aliases":[],"title":"Dasel is a command-line tool and library for querying, modifying, and transforming data structures. From 3.0.0 until 3.11.1, parsing/json/json_reader.go decodeValue, decodeObject, and decodeArray, and parsing/xml/reader.go parseElement, rec…","description":"Dasel is a command-line tool and library for querying, modifying, and transforming data structures. From 3.0.0 until 3.11.1, parsing/json/json_reader.go decodeValue, decodeObject, and decodeArray, and parsing/xml/reader.go parseElement, recurse once per input nesting level without a depth guard. Deeply nested attacker-controlled JSON or XML supplied through parsing.Format(...).NewReader(...).Read(data), the command-line interface, or the parse selector function can exhaust the Go goroutine stack and raise an unrecoverable fatal error that terminates the entire process. The XML input-size limit does not prevent depth exhaustion, and defer or recover cannot intercept the failure. This issue is fixed in version 3.11.1.","state":0,"publishedAt":"2026-09-21T17:17:36.5+00:00","modifiedAt":"2026-09-24T21:25:27.05+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":6.2,"severity":"MEDIUM"}],"references":["https://github.com/TomWright/dasel/commit/4c91d0d02dc59ce8404709b1bfed7a6fabe62f68","https://github.com/TomWright/dasel/releases/tag/v3.11.1","https://github.com/TomWright/dasel/security/advisories/GHSA-cqxr-jxr2-85pq"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-59168","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-674"],"productCriteria":[],"sourceDates":{"published":"2026-09-21T17:17:36.500","lastModified":"2026-09-24T21:25:27.050"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-59168","identifiers":["CVE-2026-59168"]},"retained":false,"historicalAffected":[]},{"revision":"2810649bbf124bc2acb75bff5df02125","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-cqxr-jxr2-85pq","aliases":["CVE-2026-59168","GO-2026-6549"],"title":"Dasel: Unbounded recursion in JSON and XML readers causes unrecoverable stack-overflow DoS","description":"## Summary\n\n`dasel`'s JSON and XML readers parse nested structures with unbounded recursion, one\nnative stack frame per nesting level, with no depth guard. A small (sub-10 MB), deeply\nnested document drives the Go runtime past its goroutine stack limit and triggers a\n`fatal error: stack overflow`. This is **unrecoverable**: it is a runtime fatal error, not\na `panic`, so a consumer's `defer`/`recover` cannot intercept it, the entire process dies.\n\nBoth readers are affected; neither has a depth limit, and the JSON reader additionally has\nno input-size cap (the XML reader caps size at 10 MB but not depth).\n\n## Affected Versions\n\n`github.com/tomwright/dasel/v3` and all v3.x releases through **v3.11.0** (current `main`,\ncommit `abc1e1d`). This vulnerability is fixed in 3.11.1. Pre-v3 is out of scope.\n\n## Description\n\n### JSON reader @ `parsing/json/json_reader.go`\n\n`decodeValue` (line 54) dispatches to the mutually-recursive `decodeObject` (line 78) and\n`decodeArray` (line 140). Each calls back into both for nested values\n(`decodeArray`→`decodeArray` at line 151, `decodeObject` at 163; `decodeObject`→`decodeArray`\nat 95, `decodeObject` at 111). Every `[` or `{` in the input adds one stack frame. There is\n**no depth counter and no `len(data)` cap** anywhere in the reader.\n\n### XML reader @`parsing/xml/reader.go`\n\n`parseElement` (line 172) recurses at line 211 for every `xml.StartElement`. The file\ndeclares explicit DoS guards — `maxXMLSize = 10_000_000`, comment count/length — but these\nbound **size and comment volume, not nesting depth**. The open tag `<a>` is 3 bytes, so the\n10 MB cap still permits ~3.3 M nesting levels, exhausting the stack long before the size\nlimit fires.\n\n### Reachability (both)\n\nBoth are on the primary public read path: `parsing.Format(<fmt>).NewReader(opts).Read(data)`,\nwith `data` fully attacker-controlled and no depth validation before the recursion. The same\npath backs the `dasel` CLI (`dasel -r json` / `-r xml`). Default reader, no special options.\nGo stack overflow is a `fatal error`, so `recover()` at the call site does not help.\n\n### Precedent in this codebase\n\nDoS hardening on the readers is already an accepted concern here, which is why this is a gap\nrather than a design choice: the XML reader has the `maxXMLSize` cap, and the **YAML reader\nalready implements exactly the fix needed**, `parsing/yaml/yaml_reader.go:31,90-93` returns\n`ErrYamlExpansionDepthExceeded` once `expansionDepth > maxExpansionDepth`. The JSON and XML\nreaders simply lack the equivalent depth guard.\n\n## Proof of Concept\n\nSingle runnable program, public API only (`poc/main.go`, module wired to a local clone via\n`replace`):\n\n```go\npackage main\n\nimport (\n\t\"fmt\"; \"os\"; \"strings\"\n\t\"github.com/tomwright/dasel/v3/parsing\"\n\t_ \"github.com/tomwright/dasel/v3/parsing/json\"\n\t_ \"github.com/tomwright/dasel/v3/parsing/xml\"\n)\n\nfunc main() {\n\tmode := \"json\"; if len(os.Args) > 1 { mode = os.Args[1] }\n\tdepth := 6_000_000; if mode == \"xml\" { depth = 3_200_000 }\n\n\tvar data []byte\n\tif mode == \"xml\" {\n\t\tdata = []byte(strings.Repeat(\"<a>\", depth))          // ~9.6MB, under the 10MB cap\n\t} else {\n\t\tdata = []byte(strings.Repeat(\"[\", depth) + strings.Repeat(\"]\", depth)) // ~12MB\n\t}\n\n\tdefer func() { if r := recover(); r != nil { fmt.Println(\"recovered (NOT fatal):\", r) } }()\n\tr, _ := parsing.Format(mode).NewReader(parsing.DefaultReaderOptions())\n\tv, err := r.Read(data)\n\tfmt.Printf(\"Read returned WITHOUT crash: v=%v err=%v\\n\", v != nil, err)\n}\n```\n\n```\ngo run . json    # nested arrays -> fatal error: stack overflow ; ~85 decodeArray frames\ngo run . xml     # nested <a>    -> fatal error: stack overflow ; ~93 parseElement frames\n```\n\nObserved (Go 1.26, default 1 GB goroutine stack):\n- `json` depth 6 M (12 MB): `runtime: goroutine stack exceeds 1000000000-byte limit` →\n  `fatal error: stack overflow`; backtrace dominated by `json.(*jsonReader).decodeArray`.\n  `depth 2 M` completes (~0.83 s), confirming it is depth-driven, not a parse error.\n- `xml` depth 3.2 M (9.6 MB, **under** the 10 MB `maxXMLSize` cap): same fatal overflow;\n  backtrace is an unbroken chain of `xml.(*xmlReader).parseElement` at `reader.go:211`.\n- The deferred `recover()` never fires in either case — the process exits.\n- CLI equivalents: `printf '<a>%.0s' {1..3200000} | dasel -r xml`.\n\n## Impact\n\nAn attacker who controls JSON or XML passed to dasel — via the library `Read` API, the CLI,\nor the `parse('json'|'xml', …)` selector function — crashes the host process with a single\nsmall document. Because the failure is a Go `fatal error` rather than a recoverable panic, a\nconsumer that wraps parsing in `defer`/`recover` is **still** taken down: the whole process\nterminates, killing every in-flight goroutine, not just the parse. Availability only — no\nconfidentiality or integrity impact. For a library consumer feeding network-sourced data to\n`Read`, this is a remotely triggerable, unrecoverable DoS.\n\n## Suggested Fix\n\nAdd a recursion-depth guard to both readers, mirroring the YAML reader's existing\n`maxExpansionDepth` / `ErrYamlExpansionDepthExceeded` pattern:\n\n- **JSON** — thread a `depth int` through `decodeValue`/`decodeObject`/`decodeArray`,\n  increment on descent, return `ErrJSONMaxDepthExceeded` past a conservative bound\n  (e.g. 10 000). Optionally add a `maxJSONSize` cap matching `maxXMLSize` for parity.\n- **XML** — add a `maxXMLDepth` constant to the existing `Security limits` block and thread\n  a `depth` through `parseElement`, returning a normal error past the bound.\n\nBoth return a clean `error` for pathological input instead of crashing the process,\nconsistent with how the comment-count, size, and YAML-expansion limits already behave. A\nlimit in the low thousands preserves all realistic legitimate documents.","state":0,"publishedAt":"2026-09-22T19:51:07+00:00","modifiedAt":"2026-10-01T20:55:54.790808+00:00","affected":[{"ecosystem":"Go","name":"github.com/tomwright/dasel/v3","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"3.0.0"},{"kind":"fixed","version":"3.11.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/TomWright/dasel/security/advisories/GHSA-cqxr-jxr2-85pq","https://nvd.nist.gov/vuln/detail/CVE-2026-59168","https://github.com/TomWright/dasel/commit/4c91d0d02dc59ce8404709b1bfed7a6fabe62f68","https://github.com/TomWright/dasel","https://github.com/TomWright/dasel/releases/tag/v3.11.1"],"sourceUrl":"https://github.com/advisories/GHSA-cqxr-jxr2-85pq","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-cqxr-jxr2-85pq","identifiers":["GHSA-cqxr-jxr2-85pq","CVE-2026-59168","GO-2026-6549"]},"retained":false,"historicalAffected":[]},{"revision":"a1a6ac0d69404264b28f2d5d4ad2b8c1","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6549","aliases":["CVE-2026-59168","GHSA-cqxr-jxr2-85pq"],"title":"Dasel: Unbounded recursion in JSON and XML readers causes unrecoverable stack-overflow DoS in github.com/tomwright/dasel","description":"Dasel: Unbounded recursion in JSON and XML readers causes unrecoverable stack-overflow DoS in github.com/tomwright/dasel","state":0,"publishedAt":"2026-10-01T20:23:38+00:00","modifiedAt":"2026-10-01T20:45:12.2230047+00:00","affected":[{"ecosystem":"Go","name":"github.com/tomwright/dasel","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/tomwright/dasel/v2","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/tomwright/dasel/v3","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"3.0.0"},{"kind":"fixed","version":"3.11.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/TomWright/dasel/security/advisories/GHSA-cqxr-jxr2-85pq","https://nvd.nist.gov/vuln/detail/CVE-2026-59168","https://github.com/TomWright/dasel/commit/4c91d0d02dc59ce8404709b1bfed7a6fabe62f68","https://github.com/TomWright/dasel/releases/tag/v3.11.1"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6549","license":"OSV · upstream source license applies","key":"osv:GO-2026-6549","identifiers":["GO-2026-6549","CVE-2026-59168","GHSA-cqxr-jxr2-85pq"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-11T20:58:42.4460032+00:00","complete":true,"records":1779,"lastAttemptAt":"2026-11-11T20:58:42.4460032+00:00","lastSuccessAt":"2026-11-11T20:58:42.6009016+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:58:42.6009024+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-de3b77103708811b6494d2ff7c979037d73ae579742cd1649a5c765137ae5083-bc2564cf749a574ebe6216cd53b2772c98ccf01e107d9e465c7cb9637c59db40","complete":true,"records":424281,"lastAttemptAt":"2026-11-11T20:56:40.1262638+00:00","lastSuccessAt":"2026-11-11T19:56:47.8167322+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:56:40.1262638+00:00","snapshotPublishedAt":"2026-11-11T19:18:45+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-cbeeeca22e4a4c188e95cc4f8cfc6560","complete":false,"records":13759,"lastAttemptAt":"2026-11-11T21:08:58.0161049+00:00","lastSuccessAt":"2026-11-11T21:08:58.011+00:00","error":"249 identifier lookups failed; latest failures include AccessDenied (HTTP 403). Other identifiers were checked independently.","lastVerifiedAt":"2026-11-11T21:08:58.011+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13368,"expectedIdentifiers":13813,"failedIdentifiers":249},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-11T20:58:42.4460032+00:00","complete":true,"records":1097,"lastAttemptAt":"2026-11-11T20:58:42.4460032+00:00","lastSuccessAt":"2026-11-11T20:58:42.6018487+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:58:42.6018491+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-f58072f00ed84b8dbc554f4a4e66e21a","complete":true,"records":13753,"lastAttemptAt":"2026-11-11T20:59:01.4643428+00:00","lastSuccessAt":"2026-11-11T20:59:01.459+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:59:01.459+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13813,"expectedIdentifiers":13813,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-3562b6c78fd1bd0f0b55daf66a0926ae24f65e462df7f6d928caad458fc696bf","complete":true,"records":9947,"lastAttemptAt":"2026-11-11T20:58:42.3041045+00:00","lastSuccessAt":"2026-11-11T04:27:43.6877707+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:58:42.3041045+00:00","snapshotPublishedAt":"2026-11-11T03:32:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-456002455e0ab94bb92c95476d4e6d175c104cd594749982afd96c893728ecbc","complete":true,"records":2010,"lastAttemptAt":"2026-11-11T20:56:40.2809572+00:00","lastSuccessAt":"2026-11-11T02:36:58.1276999+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:56:40.2809572+00:00","snapshotPublishedAt":"2026-11-11T01:17:51+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-baa8362b4daf9e5f39d5563775a55935e7b442c0735d33274a921579ce4a0d66","complete":true,"records":3093,"lastAttemptAt":"2026-11-11T20:58:42.411286+00:00","lastSuccessAt":"2026-11-11T13:00:02.5446881+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:58:42.411286+00:00","snapshotPublishedAt":"2026-11-11T12:47:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-757d3692f9a7b34792dad960197f3cc953a54db59b7d0ffe3835a0ed9926f76b","complete":true,"records":231690,"lastAttemptAt":"2026-11-11T20:58:42.1683586+00:00","lastSuccessAt":"2026-11-11T20:58:40.6131056+00:00","error":null,"lastVerifiedAt":"2026-11-11T20:58:42.1683586+00:00","snapshotPublishedAt":"2026-11-11T20:03:03+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}