{"id":"CVE-2026-44972","aliases":["GHSA-m5p4-gvpx-4mvr","PYSEC-2026-2506"],"title":"GuardDog: Unsanitized human-readable scan output allows terminal escape injection from malicious package content","summary":"GuardDog: Unsanitized human-readable scan output allows terminal escape injection from malicious package content","severity":"medium","cvss":5,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","vendor":"guarddog","product":"guarddog","ecosystem":"pip","affected":["guarddog >= 2.6.0, <= 2.9.0"],"published":"2026-05-11","updated":"2026-07-13","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-m5p4-gvpx-4mvr","references":[{"url":"https://github.com/DataDog/guarddog/security/advisories/GHSA-m5p4-gvpx-4mvr"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44972"},{"url":"https://github.com/DataDog/guarddog"}],"tags":["osv","pip"],"epss":0.00113,"epssPercentile":0.01594,"ingestedAt":"2026-07-13T18:58:00.307Z","slug":"CVE-2026-44972","body":"## Overview\n\n# Summary\nGuardDog includes attacker-controlled filenames, file locations, messages, and code snippets in its default human-readable output without escaping terminal control characters. A malicious package can therefore inject ANSI or OSC escape sequences into analyst terminals or CI logs.\n\n# Description\nThe finding formatter stores file paths and snippets from scanned content:\n\n```python\nlocation = file_path + \":\" + str(start_line)\nfinding = {\n    \"location\": location,\n    \"code\": code,\n    \"message\": result[\"extra\"][\"message\"],\n}\n```\n\nThe human-readable reporter later prints these values directly:\n\n```python\n\"  * \" + finding[\"message\"] + \" at \" + finding[\"location\"] + \"\\n    \" + _format_code_line_for_output(finding[\"code\"])\n```\n\nNo escaping is applied for control characters such as `\\x1b`. A malicious package can therefore ship a filename like:\n\n```text\nevil\\x1b[2J.py\n```\n\nor matched source lines containing terminal escapes, which survive into the final CLI output.\n\n# Reproduction summary\n1. Create a file whose name contains `\\x1b[2J`.\n2. Feed a semgrep-style result referencing that file into `Analyzer._format_semgrep_response()`.\n3. Render the result with `HumanReadableReporter.print_scan_results()`.\n4. The output string contains the raw escape bytes, which a terminal may interpret.\n\n# Key code paths\n- `guarddog/analyzer/analyzer.py:377-392`\n- `guarddog/reporters/human_readable.py:36-42`\n- `guarddog/reporters/human_readable.py:84-91`\n\n# Practical impact\nThis can be used to:\n- clear or rewrite analyst terminal output\n- inject misleading or spoofed log content in CI\n- emit clickable OSC 8 hyperlinks or title changes in compatible terminals\n\n# Prior public disclosure check\nAs of 2026-03-18, no matching public GitHub advisory, CVE, or public repo issue was found for this specific bug.\n\n# Suggested fix\nEscape or strip terminal control characters before rendering any attacker-controlled value in human-readable output. This should cover package names, file paths, messages, and code snippets.\n\n## Affected packages\n\n- `guarddog >= 2.6.0, <= 2.9.0`\n\n## Remediation\n\nRefer to the advisory for the patched release.","depth":"sunlit","depthScore":28,"depthScoreParts":{"impact":27.5,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}