Repository navigation
properties/csv/tsv/shell output encoders don't strip terminal escape sequences #2901
Description
reported on 8 Aug 2026 via https://github.com/mikefarah/yq/security/advisories/GHSA-pw25-v448-3fgf:
Description
yq's -o properties, -o csv, -o tsv, and -o shell output formats write a scalar value's string content directly to stdout with no filtering of control characters. yq's other four output formats (yaml, json, xml, toml) are not affected, because escaping control characters is an inherent, spec-mandated part of correctly serializing those formats, and the libraries yq uses for them already do this correctly.
Since a source document's string values have no character restrictions, and running yq to convert or extract values from a document is the tool's ordinary use, processing any document containing an escape sequence embedded in a string value with one of the four affected output formats writes that sequence to the user's terminal, where it is interpreted live by the terminal emulator.
Vulnerable code
pkg/yqlib/encoder_properties.go:Encode()anddoEncode()writenode.Valuedirectly (only conditionally wrapping in%qif the value contains a space, no control-character handling).pkg/yqlib/encoder_csv.go:encodeRow()passeschild.Valuedirectly toencoding/csv'sWriter.Write(), shared by both thecsvandtsvformats via a configurable separator.pkg/yqlib/encoder_shellvariables.go:doEncode()'squoteValue()correctly handles POSIX single-quote escaping (to prevent shell syntax injection if the output is latereval'd) but has no control-character filtering. Notably, the sibling functionappendPath()(used for the shell variable name) already deliberately strips non-ASCII and ASCII control characters, with a code comment explaining why; the value itself never received the same treatment.
Proof of Concept
(available upon request)
Impact
An attacker who can get a victim to process a crafted document (a config file in a repository, a downloaded file, a CI/CD artifact, a third-party Helm chart or similar) with yq -o properties, -o csv, -o tsv, or -o shell can inject terminal escape sequences into the victim's terminal.
Patches / Fix
A fix has been written and validated (a PR will follow this advisory). It adds a shared sanitizeControlChars helper in pkg/yqlib/utils.go and applies it at each of the three affected encoders' scalar-value points, before their existing format-specific quoting logic runs. Re-tested against all four affected formats after the fix: the injected escape bytes are fully removed, only harmless printable text remains, and the project's existing test suite passes unchanged (two unrelated, pre-existing test failures were confirmed via git stash to also occur before this fix).
Workarounds
None identified; avoid piping yq -o properties/csv/tsv/shell output from untrusted documents directly to an interactive terminal until patched, or strip control characters from the output yourself (e.g. | tr -d '\000-\010\013\014\016-\037\177', preserving tab and newline) as a temporary mitigation.
Activity