Written by: Jacob Thompson
The Apache XML Security for C++ library, code named xml-security-c
, is part of the Apache Santuario project. The library implements the XML Digital Signature and the XML Signature specifications, making them available to C++ developers. By default, the library resolves references to external URIs passed in Extensible Markup Language (XML) signatures, allowing for server-side request forgery (SSRF). There is no way to disable this feature through configuration alone, and there is no patch available; the developer must either scan their codebase to find every usage of xml-security-c
and override the URI resolver to avoid SSRF, or manually patch and recompile the library to remove the capability entirely. We recommend that C++ developers using XML audit their code bases for usage of this library and determine whether they have introduced a security vulnerability, and if so, modify their code to avoid SSRF.
Background
Server-side request forgery (SSRF) is a class of security vulnerability in which an untrusted party tricks a server into making an HTTP request by passing the server a malicious input. Although the attacker usually cannot view the response, requests to the loopback interface (127.0.0.1
), RFC 1918 addresses (e.g., 10.0.0.0/8
or 192.168.0.0/16
), or any other destination occur from the point of view of the server, allowing requests that would otherwise be restricted by firewall rules or that would be impossible to perform externally. Consider the obvious consequences if a server’s uninterruptible power supply offers a web service bound to 127.0.0.1:8080
without authentication and that accepts a GET request http://127.0.0.1:8080/ups/changePowerState?state=off
—and what happens if this service is reachable via server-side request forgery.
The Extensible Markup Language (XML) is complex and contains many optional features that are not suitable or even useful in the common case of a server accepting untrusted XML documents on an external interface. Some allow cross-site request forgery just by initializing an XML parser in its default configuration and passing an untrusted document. For example, XML External Entities allow a document to define custom entity values (analogous to <
meaning <
in HTML) to be replaced by the response from an external URL or the contents of a local file rather than a static string. Despite no real-world relevance to a server accepting and parsing untrusted, potentially malicious documents, this feature was enabled by default in many parsers and plagued the 2010s decade; XML External Entity Injection was promoted to an item in the OWASP Top Ten in 2017. Current versions of many XML parsers have now been hardened to treat support for external entities, document-type definitions, schemas, and so forth as an opt-in feature that is disabled by default. In this post, we present a different form of server-side request forgery affecting XML documents. We have found this issue being actively exploited; it was recently addressed by Ivanti in CVE-2024-21893.
XML Signatures External URI Feature
The XML Signature specification standardizes a way to digitally sign XML documents. The specification includes features that, from a security perspective, introduce additional paths to server-side request forgery into XML, beyond XML External Entity Injection. The XML Signature Syntax and Processing Version 2.0 specification states that “We RECOMMEND XML Signature applications be able to dereference URIs in the HTTP scheme,” which, absent other protections such as egress firewall rules, allows for SSRF. This recommendation is carried over from version 1.1 of the specification and therefore version 1.x signatures are also affected.
Figure 1 shows a simple XML document that, when parsed by xml-security-c
version 2.0.4 and earlier, causes the parser to make an HTTP request to http://www.example.com/ssrf
.
<test>
<ds:Signature xmlns:ds=
"http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm=
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm=
"http://www.w3.org/2000/09/xmldsig#Manifest"/>
<ds:Reference URI="http://www.example.com/ssrf">
<ds:Transforms>
<ds:Transform Algorithm=
"http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm=
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAA==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509SubjectName>CN=nobody</ds:X509SubjectName>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</test>
Figure 1: Sample XML document to trigger SSRF in affected xml-security-c library
Prior Work
Other open-source projects have already identified and modified their software to work around this issue. The Shibboleth xmltooling
project reported a server-side request forgery vulnerability as CVE-2023-36661 and implemented a workaround in the xmltooling
code to override the default, non-secure URI resolver in xml-security-c
with a custom one that does nothing. While this mitigation is sufficient to resolve the issue in xmltooling
—so long as every possible instance of xml-security-c
is located and fixed—the root cause arguably lies in the xml-security-c
library not being secure by default. Fixing the issue in xmltooling
rather than upstream did not help other users of xml-security-c
who were not aware of the need to reconfigure it.
Dangerous XML features such as the ability to make external network requests just by parsing a document should, in our view, be disabled in the default configuration and then only enabled when parsing documents from a trusted source. In fact, a different library under the Apache Santuario project, Apache XML Security for Java, has a “secure validation” feature that is enabled by default. Among other characteristics, the secure validation feature “[d]oes not allow a Reference to call the ResolverLocalFilesystem or the ResolverDirectHTTP (references to local files and HTTP resources are forbidden).” Thus, Java developers, unlike C++ developers, are already protected against SSRF in the default configuration of the Java port of the library. The secure validation feature never made it to the C++ version.
Disclosure
Mandiant reported the non-secure default configuration in xml-security-c
to the Apache Software Foundation (ASF). As external URI resolution is a legitimate feature in the XML Digital Signature specification, the ASF did not issue a CVE or a new release of xml-security-c
. The Apache Santuario project did add a new disclaimer for xml-security-c
shown in Figure 2, suggesting that XML Signatures and XML Encryption are difficult to implement securely; that xml-security-c
is not secure by default and does not provide hardening configuration options; and that the library is not modular, making it difficult to ever add such features. Going forward, Apache Santuario is no longer supported as a standalone library, and the Shibboleth project will be taking over the project as a component of Shibboleth only. The developers suggest finding another solution.
Recommendations
C++ developers should first scan their projects to determine if they use the Apache xml-security-c
library. If so, the software may have a server-side request forgery vulnerability unless the code is patched.
In some cases, usage of xml-security-c
may be very limited, or it may be inconvenient to recompile the library when it is obtained in binary form. If developers can pinpoint each use of the XSECProvider
class, they can call the setDefaultURIResolver
method on the XSECProvider
object, passing a custom implementation of XSECURIResolver
that simply does nothing. This avoids the need to recompile xml-security-c
and ensures the software remains secure if it is ever linked against the stock xml-security-c
.
An alternative, and in our view superior approach, is to patch the xml-security-c
library to make it secure by default with regard to URI resolution. Mandiant developed a patch to supersede the vulnerable XSECURIResolverXerces
with a new default XSECURIResolverNoop
that does nothing, thus fixing the SSRF. By applying the patch and recompiling, the library will not be susceptible to this form of SSRF. Note that any legitimate uses of external URIs would need to be changed to manually specify XSECURIResolverXerces
as the default URI resolver.
The patch is available for download now (note: the download is a ZIP file, which contains the patch as a TXT file).
Source: Original Post