CVE-2020-29510
Executive Summary
CVE-2020-29510 is a critical input-validation flaw in the encoding/xml package of Golang (Go) versions 1.15 and earlier. The vulnerability stems from incorrect preservation of XML directive semantics during tokenization round-trips, allowing crafted inputs to be interpreted differently at various processing stages in downstream applications. With a CVSS score of 9.8, the flaw exposes affected applications to potential XML parser confusion, which can lead to authentication bypass, data corruption, or injection attacks, depending on how the downstream application consumes the parsed XML. Enterprises running Go-based services that accept untrusted XML input are at highest risk.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability resides in the encoding/xml package of the Go standard library, specifically in its tokenization logic. The NVD description states that the package "does not correctly preserve the semantics of directives during tokenization round-trips." Directives in XML include processing instructions, DOCTYPE declarations, and comments — constructs that the tokenizer must preserve exactly to maintain a consistent view of the document across multiple parse passes.
Vulnerability Mechanism:
When a Go application tokenizes an XML document (using xml.Decoder.Token() or similar), the tokenizer converts raw XML bytes into structured tokens. If the application later re-serializes those tokens (e.g., using xml.EscapeText() or by feeding tokens back into an encoder), the reconstructed XML may differ semantically from the original. This discrepancy is specifically tied to directives — the tokenizer fails to preserve their exact byte-level representation. As a result, an attacker can craft an XML document that appears benign when first parsed, but transforms into a malicious document during a second pass, affecting downstream logic that relies on parse consistency.
Attack Surface: The attack surface encompasses any Go application (version 1.15 or earlier) that:
- Accepts XML input from untrusted sources (HTTP APIs, file uploads, message queues).
- Processes the XML through multi-pass parsing (e.g., validating once, then forwarding).
- Makes security decisions (authentication, authorization, input validation) based on the initial parse, but uses the re-serialized output for execution or storage.
The vulnerability is a classic "parser differential" or "billion laughs"-adjacent issue in the XML family of weaknesses, but unique in that it targets Go's specific tokenization semantics rather than entity expansion or DTD processing.
Code-Level Context: No specific function names or line numbers are available from the NVD description. The fault lies in how the tokenizer handles XML directives during round-trip operations — likely involving lossy conversion of raw directive text into token structs that omit certain attributes or whitespace, which then get re-encoded differently. Without access to the Go source at the affected revision, exact code paths remain unverified.
CVSS Rationale: The 9.8 score (Critical) reflects: network-exploitable, low attack complexity, no privileges required, no user interaction, and high impact across confidentiality, integrity, and availability. The attack vector is remote (AV:N), and exploitation does not require special conditions beyond delivering a crafted XML payload to the target application.
Exploitation Scenarios
Attack Chain (inferred from vulnerability class; no public PoC):
Reconnaissance/Identification: The attacker identifies a Go-based web service (version 1.15 or earlier) that accepts XML input — e.g., a REST API with
Content-Type: application/xml, a SOAP endpoint, or an XML-RPC handler. The attacker may fingerprint the Go version via HTTP headers (Server: Go-http-server), response header ordering, or behavioral fingerprinting.Triggering the Flaw: The attacker crafts an XML document containing malicious directives — for example, a DOCTYPE declaration or processing instruction that is ambiguous. The document is constructed so that, when tokenized and re-serialized by the
encoding/xmlpackage, the directive's semantic meaning changes. For instance, a directive that appears as a harmless comment in the first pass becomes an active processing instruction in the second pass, or a DOCTYPE that is dropped/reordered upon re-encoding.Payload/Execution: At the vulnerability-class level, this is an XML semantic-confusion attack. The attacker delivers the payload via a normal request to the vulnerable endpoint. The downstream application performs a round-trip (parse → re-encode → parse again, or parse → transform → store), during which the directive corruption occurs. The second-stage parser now processes a structurally different document. If the application uses the first parse for validation (e.g., whitelist checks on element names) and the second parse for execution, the attacker bypasses validation and injects unintended elements, attributes, or processing instructions that trigger business-logic flaws — such as privilege escalation, data exfiltration via XXE (if the second parser enables external entity resolution), or denial of service via malformed deep structures.
Post-Exploitation Impact: Successful exploitation gives the attacker the ability to manipulate application behavior in ways inconsistent with the developer's intent. This can range from bypassing XML-based authentication to injecting content into downstream data stores or triggering XXE-based file reads if the second-stage parser is configured permissively — although XXE behavior is not directly specified in this CVE, the semantic-confusion flaw could make such attacks viable.
Important Note: No public proof-of-concept is available, and exploitability depends heavily on the downstream application's specific XML processing pipeline. The attack chain is inferred from the vulnerability class (XML parser differential) and should be treated as a high-risk but not fully weaponized threat.
Impact Assessment
Business Impact:
- Confidentiality: If XXE or entity-injection becomes viable post round-trip, sensitive files (e.g.,
/etc/passwd) or internal network resources could be disclosed. - Integrity: Crafted directives could alter the semantic meaning of XML data that feeds business logic, leading to data corruption, unauthorized transactions, or bypassed access controls.
- Availability: Malformed directive round-trips could cause parser crashes or infinite loops in edge cases, leading to denial of service.
Affected Systems:
- All Go applications built with Go ≤ 1.15 that process untrusted XML with
encoding/xml. - Particularly at risk: API gateways, microservices, data ingestion pipelines, and any service that parses XML in a "sanitize-then-use" pattern.
- The vulnerability is language-level, so it affects all downstream applications regardless of vendor, making the blast radius extremely broad within Go ecosystems.
Blast Radius:
- CVSS 9.8 with the full confidentiality/integrity/availability triad at High impact. The attack vector is remote and unauthenticated, meaning internet-facing Go XML endpoints are directly exposed.
- EPSS score of 0.02047 (79.4th percentile) suggests that while public exploitation is not yet widespread, the CVE is part of the heavier tail of known-exploited vulnerabilities and should be prioritized.
CWE Mapping: The NVD lists no CWE, but the most appropriate mapping is CWE-20 (Improper Input Validation) or CWE-436 (Interpretation Conflict). I recommend CWE-436 given the semantic-confusion nature of the flaw.
Detection Guidance
Sigma Rule
title: Go XML Directive Round-Trip Anomaly Detection
id: 4f7a2b1c-9d3e-4a5b-8c6d-1e2f3a4b5c6d
status: experimental
description: Detects HTTP requests to Go services containing suspicious XML directives that may trigger CVE-2020-29510 round-trip corruption.
author: valtersit.com
logsource:
category: webserver
product: generic
detection:
selection_xml_content_type:
cs-method: POST
cs-content-type|startswith: application/xml
selection_suspicious_directives:
cs-uri-query|contains:
- '<!DOCTYPE'
- '<?'
- '<!--'
selection_multiple_parse_headers:
cs-user-agent|contains:
- 'Go-http-client'
condition: selection_xml_content_type and selection_suspicious_directives and selection_multiple_parse_headers
falsepositives:
- Legitimate XML APIs that process DOCTYPE declarations (rare)
- Automated tools sending XML probes
level: high
tags:
- attack.t1190
- cve.2020-29510
YARA Rule
rule Go_XML_Roundtrip_CVE_2020_29510
{
meta:
author = "valtersit.com"
description = "Detects XML payloads with directive patterns that exploit Go encoding/xml round-trip semantic confusion in Go <= 1.15"
cve = "CVE-2020-29510"
severity = "critical"
date = "2024-01-01"
strings:
$doctype = /<!DOCTYPE\s+[a-zA-Z0-9_-]+\s+\[/ nocase
$pi = /<\?[a-zA-Z][a-zA-Z0-9_-]*\s/ nocase
$comment = /<!--[\s\S]{10,}-->/ nocase
$nested = /<!DOCTYPE[\s\S]{0,200}<!\[CDATA\[/ nocase
$reencode_hint = /(?:encode|escape|roundtrip|reparse)/ nocase
condition:
any of ($doctype, $pi) and any of ($comment, $nested) or $reencode_hint
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2020-29510 Go XML Directive Round-Trip Attempt"; flow:to_server,established; content:"POST"; http_method; content:"application/xml"; http_content_type; content:"<!DOCTYPE"; http_client_body; nocase; pcre:"/<!DOCTYPE\s+[a-zA-Z0-9_-]+\s+\[[^\]]{0,500}/i"; sid:2951001; rev:1; metadata:cve CVE-2020-29510; classtype:attempted-admin;)
Elastic Detection
// EQL query for detecting anomalous XML directive patterns in HTTP requests
sequence by source.ip, user_agent
[network where event.type == "connection" and network.protocol == "http"]
[http where request.headers.content-type contains "application/xml" and
wildcard(request.body.text, "*<!DOCTYPE*") and
not wildcard(request.body.text, "*<svg*")]
Splunk SPL Query
index=web sourcetype=access_combined
| where like(form_data, "%<!DOCTYPE%") OR like(form_data, "%<?xml%")
| search form_data="*<![CDATA[*" OR form_data="*<script*"
| eval xml_directives = mvcount(split(form_data, "<"))
| where xml_directives > 5
| stats count by src_ip, uri_path, form_data, _time
| sort - count
| table _time, src_ip, uri_path, form_data, count
Wazuh OSSEC Rule
<group name="xml_exploitation">
<rule id="295100" level="15">
<if_sid>31100</if_sid>
<match>POST</match>
<regex>Content-Type:\s*application/xml</regex>
<regex><\!DOCTYPE</regex>
<description>CVE-2020-29510 - Go XML directive round-trip manipulation attempt blocked</description>
<group>xml</group>
<mitre>
<id>T1190</id>
</mitre>
<options>no_full_log</options>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 1/4 — Partial (workaround only, no official fix confirmed)
Immediate Mitigations (do these now):
- Validate XML with external tooling: Before processing untrusted XML with Go's
encoding/xml, run the input through thegithub.com/mattermost/xml-roundtrip-validatormodule. This library performs a tokenization round-trip and compares the output to the input, flagging any discrepancies that indicate directive semantic corruption. Only accept XML that passes validation. - Disable DOCTYPE/entity processing: Configure downstream XML parsers to reject DOCTYPE declarations and processing instructions. If using a wrapper library, strip these directives before they reach Go's tokenizer.
- Apply web application firewall (WAF) rules: Block POST requests with
application/xmlcontent type that contain<!DOCTYPEor raw<?directives, unless business requirements dictate otherwise.
- Validate XML with external tooling: Before processing untrusted XML with Go's
Patch/Upgrade Steps:
- Upgrade Go: The definitive fix is to upgrade the Go toolchain to version 1.16 or later, which contains the corrected
encoding/xmltokenization logic (assuming the Go team shipped a fix in a subsequent release; if not, monitor for the Go security advisory). - Rebuild affected applications: After upgrading, rebuild all Go binaries that handle XML and redeploy to staging for regression testing before production rollout.
- Track vendor advisory: Monitor the Go security mailing list (golang-announce) for the official advisory and version-specific fix notes.
- Upgrade Go: The definitive fix is to upgrade the Go toolchain to version 1.16 or later, which contains the corrected
Long-Term Hardening:
- Adopt strict XML schema validation: Enforce XSD validation using a third-party, actively maintained XML library that does not rely on Go's standard library tokenization. Consider
github.com/beevik/etreeorgithub.com/antchfx/xmlqueryfor parsing, with external validation layers. - Implement defense-in-depth: Use content security policy (CSP), input length limits, and rate limiting on XML endpoints to reduce automated probing window.
- Application isolation: Run XML-parsing services in containers with minimal privileges, seccomp profiles, and network policies to contain any successful exploit.
- Incident response readiness: Add custom Sigma/YARA rules (above) to SIEM/SOAR pipelines to detect and alert on XML directive anomalies in real time.
- Adopt strict XML schema validation: Enforce XSD validation using a third-party, actively maintained XML library that does not rely on Go's standard library tokenization. Consider
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2020-29510
- Mattermost XML Round-Trip Validator: https://github.com/mattermost/xml-roundtrip-validator
- Go Security Advisories: https://groups.google.com/g/golang-announce (monitor for CVE-2020-29510-specific notification)
- GitHub Advisory: https://github.com/advisories?query=CVE-2020-29510 (check for supplementary community analysis)
- Exploit-DB / Packet Storm: https://www.exploit-db.com/search?q=CVE-2020-29510 (monitor for future PoC releases)
Threat Actor Activity: As of this report, there is no public evidence of in-the-wild exploitation, no CISA KEV listing, and no known threat actor campaigns targeting this CVE. The EPSS score (0.02047, 79.4th percentile) suggests elevated interest but not confirmed operational use. Organizations should still prioritize remediation given the critical CVSS score and the ease of developing a functional exploit against common Go XML processing patterns.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.