Moderate severityNVD Advisory· Published Jan 11, 2014· Updated Apr 29, 2026
CVE-2013-4517
CVE-2013-4517
Description
Apache Santuario XML Security for Java before 1.5.6, when applying Transforms, allows remote attackers to cause a denial of service (memory consumption) via crafted Document Type Definitions (DTDs), related to signatures.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.santuario:xmlsecMaven | < 1.5.6 | 1.5.6 |
Affected products
19cpe:2.3:a:apache:santuario_xml_security_for_java:*:*:*:*:*:*:*:*+ 17 more
- cpe:2.3:a:apache:santuario_xml_security_for_java:*:*:*:*:*:*:*:*range: <=1.5.5
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.3.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.4:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.5:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.6:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.7:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.4.8:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.5.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.5.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.5.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.5.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:santuario_xml_security_for_java:1.5.4:*:*:*:*:*:*:*
Patches
1a09b9042f775Disallow doc type declarations when secure validation is enabled
45 files changed · +157 −40
src/main/java/org/apache/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java+6 −0 modified@@ -30,6 +30,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.util.Set; + import javax.xml.crypto.*; import javax.xml.crypto.dom.DOMCryptoContext; import javax.xml.crypto.dsig.TransformException; @@ -112,6 +113,8 @@ public Data canonicalize(Data data, XMLCryptoContext xc, OutputStream os) if (apacheCanonicalizer == null) { try { apacheCanonicalizer = Canonicalizer.getInstance(getAlgorithm()); + boolean secVal = Utils.secureValidation(xc); + apacheCanonicalizer.setSecureValidation(secVal); if (log.isDebugEnabled()) { log.debug("Created canonicalizer for algorithm: " + getAlgorithm()); } @@ -249,6 +252,9 @@ public Data transform(Data data, XMLCryptoContext xc, OutputStream os) } } + boolean secVal = Utils.secureValidation(xc); + in.setSecureValidation(secVal); + try { in = apacheTransform.performTransform(in, os); if (!in.isNodeSet() && !in.isElement()) {
src/main/java/org/apache/jcp/xml/dsig/internal/dom/ApacheTransform.java+3 −1 modified@@ -28,10 +28,10 @@ import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import java.util.Set; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; - import org.apache.xml.security.signature.XMLSignatureInput; import org.apache.xml.security.transforms.Transform; import org.apache.xml.security.transforms.Transforms; @@ -187,6 +187,8 @@ private Data transformIt(Data data, XMLCryptoContext xc, OutputStream os) throw new TransformException(ex); } } + boolean secVal = Utils.secureValidation(xc); + in.setSecureValidation(secVal); try { if (os != null) {
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java+2 −0 modified@@ -64,6 +64,8 @@ public Data transform(Data data, XMLCryptoContext xc) if (subTree.excludeComments()) { try { apacheCanonicalizer = Canonicalizer.getInstance(C14N_11); + boolean secVal = Utils.secureValidation(xc); + apacheCanonicalizer.setSecureValidation(secVal); } catch (InvalidCanonicalizerException ice) { throw new TransformException ("Couldn't find Canonicalizer for: " +
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java+2 −0 modified@@ -61,6 +61,8 @@ public Data transform(Data data, XMLCryptoContext xc) try { apacheCanonicalizer = Canonicalizer.getInstance (CanonicalizationMethod.INCLUSIVE); + boolean secVal = Utils.secureValidation(xc); + apacheCanonicalizer.setSecureValidation(secVal); } catch (InvalidCanonicalizerException ice) { throw new TransformException ("Couldn't find Canonicalizer for: " +
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java+3 −1 modified@@ -33,8 +33,8 @@ import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import java.util.*; -import org.w3c.dom.Element; +import org.w3c.dom.Element; import org.apache.xml.security.c14n.Canonicalizer; import org.apache.xml.security.c14n.InvalidCanonicalizerException; @@ -144,6 +144,8 @@ public Data transform(Data data, XMLCryptoContext xc) try { apacheCanonicalizer = Canonicalizer.getInstance (CanonicalizationMethod.EXCLUSIVE); + boolean secVal = Utils.secureValidation(xc); + apacheCanonicalizer.setSecureValidation(secVal); } catch (InvalidCanonicalizerException ice) { throw new TransformException ("Couldn't find Canonicalizer for: " +
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMReference.java+3 −0 modified@@ -494,6 +494,9 @@ private byte[] transform(Data dereferencedData, } else { throw new XMLSignatureException("unrecognized Data type"); } + + boolean secVal = Utils.secureValidation(context); + xi.setSecureValidation(secVal); if (context instanceof XMLSignContext && c14n11 && !xi.isOctetStream() && !xi.isOutputStreamSet()) { TransformService spi = null;
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java+2 −1 modified@@ -235,8 +235,9 @@ public XMLStructure dereferenceAsXMLStructure(XMLCryptoContext context) { try { ApacheData data = (ApacheData)dereference(context); + boolean secVal = Utils.secureValidation(context); DocumentBuilder db = - org.apache.xml.security.utils.XMLUtils.createDocumentBuilder(false); + org.apache.xml.security.utils.XMLUtils.createDocumentBuilder(false, secVal); Document doc = db.parse(new ByteArrayInputStream (data.getXMLSignatureInput().getBytes())); Element kiElem = doc.getDocumentElement();
src/main/java/org/apache/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java+1 −0 modified@@ -90,6 +90,7 @@ public Data dereference(URIReference uriRef, XMLCryptoContext context) } XMLSignatureInput result = new XMLSignatureInput(referencedElem); + result.setSecureValidation(secVal); if (!uri.substring(1).startsWith("xpointer(id(")) { result.setExcludeComments(true); }
src/main/java/org/apache/xml/security/c14n/Canonicalizer.java+16 −1 modified@@ -98,6 +98,7 @@ public class Canonicalizer { new ConcurrentHashMap<String, Class<? extends CanonicalizerSpi>>(); private final CanonicalizerSpi canonicalizerSpi; + private boolean secureValidation; /** * Constructor Canonicalizer @@ -248,7 +249,7 @@ public byte[] canonicalize(byte[] inputBytes) InputSource in = new InputSource(bais); // needs to validate for ID attribute normalization - DocumentBuilder db = XMLUtils.createDocumentBuilder(true); + DocumentBuilder db = XMLUtils.createDocumentBuilder(true, secureValidation); /* * for some of the test vectors from the specification, @@ -286,6 +287,7 @@ public byte[] canonicalize(byte[] inputBytes) * @throws CanonicalizationException */ public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeSubTree(node); } @@ -299,6 +301,7 @@ public byte[] canonicalizeSubtree(Node node) throws CanonicalizationException { */ public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeSubTree(node, inclusiveNamespaces); } @@ -312,6 +315,7 @@ public byte[] canonicalizeSubtree(Node node, String inclusiveNamespaces) */ public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); } @@ -327,6 +331,7 @@ public byte[] canonicalizeXPathNodeSet(NodeList xpathNodeSet) public byte[] canonicalizeXPathNodeSet( NodeList xpathNodeSet, String inclusiveNamespaces ) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces); } @@ -340,6 +345,7 @@ public byte[] canonicalizeXPathNodeSet( */ public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet); } @@ -354,6 +360,7 @@ public byte[] canonicalizeXPathNodeSet(Set<Node> xpathNodeSet) public byte[] canonicalizeXPathNodeSet( Set<Node> xpathNodeSet, String inclusiveNamespaces ) throws CanonicalizationException { + canonicalizerSpi.secureValidation = secureValidation; return canonicalizerSpi.engineCanonicalizeXPathNodeSet(xpathNodeSet, inclusiveNamespaces); } @@ -382,5 +389,13 @@ public String getImplementingCanonicalizerClass() { public void notReset() { canonicalizerSpi.reset = false; } + + public boolean isSecureValidation() { + return secureValidation; + } + + public void setSecureValidation(boolean secureValidation) { + this.secureValidation = secureValidation; + } }
src/main/java/org/apache/xml/security/c14n/CanonicalizerSpi.java+2 −1 modified@@ -39,6 +39,7 @@ public abstract class CanonicalizerSpi { /** Reset the writer after a c14n */ protected boolean reset = false; + protected boolean secureValidation; /** * Method canonicalize @@ -58,7 +59,7 @@ public byte[] engineCanonicalize(byte[] inputBytes) java.io.InputStream bais = new ByteArrayInputStream(inputBytes); InputSource in = new InputSource(bais); - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation); Document document = db.parse(in); return this.engineCanonicalizeSubTree(document);
src/main/java/org/apache/xml/security/encryption/AbstractSerializer.java+13 −0 modified@@ -39,6 +39,7 @@ public abstract class AbstractSerializer implements Serializer { protected Canonicalizer canon; + protected boolean secureValidation; public void setCanonicalizer(Canonicalizer canon) { this.canon = canon; @@ -98,6 +99,7 @@ public byte[] serializeToByteArray(Element element) throws Exception { @Deprecated public String serialize(NodeList content) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); + canon.setSecureValidation(secureValidation); canon.setWriter(baos); canon.notReset(); for (int i = 0; i < content.getLength(); i++) { @@ -119,6 +121,7 @@ public String serialize(NodeList content) throws Exception { */ public byte[] serializeToByteArray(NodeList content) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); + canon.setSecureValidation(secureValidation); canon.setWriter(baos); canon.notReset(); for (int i = 0; i < content.getLength(); i++) { @@ -136,6 +139,7 @@ public byte[] serializeToByteArray(NodeList content) throws Exception { @Deprecated public String canonSerialize(Node node) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); + canon.setSecureValidation(secureValidation); canon.setWriter(baos); canon.notReset(); canon.canonicalizeSubtree(node); @@ -152,6 +156,7 @@ public String canonSerialize(Node node) throws Exception { */ public byte[] canonSerializeToByteArray(Node node) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); + canon.setSecureValidation(secureValidation); canon.setWriter(baos); canon.notReset(); canon.canonicalizeSubtree(node); @@ -245,5 +250,13 @@ protected static String createContext(String source, Node ctx) { sb.append(">" + source + "</dummy>"); return sb.toString(); } + + public boolean isSecureValidation() { + return secureValidation; + } + + public void setSecureValidation(boolean secureValidation) { + this.secureValidation = secureValidation; + } }
src/main/java/org/apache/xml/security/encryption/DocumentSerializer.java+1 −1 modified@@ -69,7 +69,7 @@ public Node deserialize(String source, Node ctx) throws XMLEncryptionException { */ private Node deserialize(Node ctx, InputSource inputSource) throws XMLEncryptionException { try { - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation); Document d = db.parse(inputSource); Document contextDocument = null;
src/main/java/org/apache/xml/security/encryption/XMLCipher.java+6 −0 modified@@ -1092,6 +1092,9 @@ private EncryptedData encryptData( if (algorithm == null) { throw new XMLEncryptionException("XMLCipher instance without transformation specified"); } + if (serializer instanceof AbstractSerializer) { + ((AbstractSerializer)serializer).setSecureValidation(secureValidation); + } byte[] serializedOctets = null; if (serializedData == null) { @@ -1604,6 +1607,9 @@ private Document decryptElement(Element element) throws XMLEncryptionException { if (log.isDebugEnabled()) { log.debug("Decrypting element..."); } + if (serializer instanceof AbstractSerializer) { + ((AbstractSerializer)serializer).setSecureValidation(secureValidation); + } if (cipherMode != DECRYPT_MODE) { log.error("XMLCipher unexpectedly not in DECRYPT_MODE...");
src/main/java/org/apache/xml/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java+1 −1 modified@@ -266,7 +266,7 @@ private Element obtainReferenceElement(XMLSignatureInput resource) */ private Element getDocFromBytes(byte[] bytes) throws KeyResolverException { try { - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation); Document doc = db.parse(new ByteArrayInputStream(bytes)); return doc.getDocumentElement(); } catch (SAXException ex) {
src/main/java/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java+8 −8 modified@@ -96,7 +96,7 @@ public PublicKey engineLookupAndResolvePublicKey( } return null; } - Element e = obtainReferenceElement(resource); + Element e = obtainReferenceElement(resource, secureValidation); // Check to make sure that the reference is not to another RetrievalMethod // which points to this element @@ -111,7 +111,7 @@ public PublicKey engineLookupAndResolvePublicKey( } RetrievalMethod rm2 = new RetrievalMethod(e, baseURI); XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation); - Element e2 = obtainReferenceElement(resource2); + Element e2 = obtainReferenceElement(resource2, secureValidation); if (e2 == element) { if (log.isDebugEnabled()) { log.debug("Error: Can't have RetrievalMethods pointing to each other"); @@ -166,7 +166,7 @@ public X509Certificate engineLookupResolveX509Certificate( return getRawCertificate(resource); } - Element e = obtainReferenceElement(resource); + Element e = obtainReferenceElement(resource, secureValidation); // Check to make sure that the reference is not to another RetrievalMethod // which points to this element @@ -181,7 +181,7 @@ public X509Certificate engineLookupResolveX509Certificate( } RetrievalMethod rm2 = new RetrievalMethod(e, baseURI); XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation); - Element e2 = obtainReferenceElement(resource2); + Element e2 = obtainReferenceElement(resource2, secureValidation); if (e2 == element) { if (log.isDebugEnabled()) { log.debug("Error: Can't have RetrievalMethods pointing to each other"); @@ -259,7 +259,7 @@ private static PublicKey resolveKey( return null; } - private static Element obtainReferenceElement(XMLSignatureInput resource) + private static Element obtainReferenceElement(XMLSignatureInput resource, boolean secureValidation) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException, KeyResolverException { Element e; @@ -271,7 +271,7 @@ private static Element obtainReferenceElement(XMLSignatureInput resource) } else { // Retrieved resource is an inputStream byte inputBytes[] = resource.getBytes(); - e = getDocFromBytes(inputBytes); + e = getDocFromBytes(inputBytes, secureValidation); // otherwise, we parse the resource, create an Element and delegate if (log.isDebugEnabled()) { log.debug("we have to parse " + inputBytes.length + " bytes"); @@ -320,9 +320,9 @@ private static XMLSignatureInput resolveInput( * @return the Document Element after parsing bytes * @throws KeyResolverException if something goes wrong */ - private static Element getDocFromBytes(byte[] bytes) throws KeyResolverException { + private static Element getDocFromBytes(byte[] bytes, boolean secureValidation) throws KeyResolverException { try { - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation); Document doc = db.parse(new ByteArrayInputStream(bytes)); return doc.getDocumentElement(); } catch (SAXException ex) {
src/main/java/org/apache/xml/security/signature/Manifest.java+4 −0 modified@@ -602,4 +602,8 @@ public int getSignedContentLength() { public String getBaseLocalName() { return Constants._TAG_MANIFEST; } + + public boolean isSecureValidation() { + return secureValidation; + } }
src/main/java/org/apache/xml/security/signature/SignedInfo.java+7 −3 modified@@ -177,15 +177,15 @@ public SignedInfo( Element element, String baseURI, boolean secureValidation ) throws XMLSecurityException { // Parse the Reference children and Id attribute in the Manifest - super(reparseSignedInfoElem(element), baseURI, secureValidation); + super(reparseSignedInfoElem(element, secureValidation), baseURI, secureValidation); c14nMethod = XMLUtils.getNextElement(element.getFirstChild()); signatureMethod = XMLUtils.getNextElement(c14nMethod.getNextSibling()); this.signatureAlgorithm = new SignatureAlgorithm(signatureMethod, this.getBaseURI(), secureValidation); } - private static Element reparseSignedInfoElem(Element element) + private static Element reparseSignedInfoElem(Element element, boolean secureValidation) throws XMLSecurityException { /* * If a custom canonicalizationMethod is used, canonicalize @@ -207,9 +207,11 @@ private static Element reparseSignedInfoElem(Element element) try { Canonicalizer c14nizer = Canonicalizer.getInstance(c14nMethodURI); + c14nizer.setSecureValidation(secureValidation); byte[] c14nizedBytes = c14nizer.canonicalizeSubtree(element); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = + XMLUtils.createDocumentBuilder(false, secureValidation); Document newdoc = db.parse(new ByteArrayInputStream(c14nizedBytes)); Node imported = @@ -267,6 +269,7 @@ public byte[] getCanonicalizedOctetStream() if (this.c14nizedBytes == null) { Canonicalizer c14nizer = Canonicalizer.getInstance(this.getCanonicalizationMethodURI()); + c14nizer.setSecureValidation(isSecureValidation()); this.c14nizedBytes = c14nizer.canonicalizeSubtree(this.constructionElement); @@ -288,6 +291,7 @@ public void signInOctetStream(OutputStream os) if (this.c14nizedBytes == null) { Canonicalizer c14nizer = Canonicalizer.getInstance(this.getCanonicalizationMethodURI()); + c14nizer.setSecureValidation(isSecureValidation()); c14nizer.setWriter(os); String inclusiveNamespaces = this.getInclusiveNamespaces();
src/main/java/org/apache/xml/security/signature/XMLSignatureInput.java+10 −1 modified@@ -85,6 +85,7 @@ public class XMLSignatureInput { * A cached bytes */ private byte[] bytes = null; + private boolean secureValidation; /** * Some Transforms may require explicit MIME type, charset (IANA registered @@ -548,7 +549,7 @@ public void setNodeSet(boolean b) { void convertToNodes() throws CanonicalizationException, ParserConfigurationException, IOException, SAXException { - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, secureValidation); // select all nodes, also the comments. try { db.setErrorHandler(new org.apache.xml.security.utils.IgnoreAllErrorHandler()); @@ -574,5 +575,13 @@ void convertToNodes() throws CanonicalizationException, this.bytes = null; } } + + public boolean isSecureValidation() { + return secureValidation; + } + + public void setSecureValidation(boolean secureValidation) { + this.secureValidation = secureValidation; + } }
src/main/java/org/apache/xml/security/transforms/implementations/TransformBase64Decode.java+13 −4 modified@@ -109,10 +109,13 @@ protected XMLSignatureInput enginePerformTransform( traverseElement((Element)el, sb); if (os == null) { byte[] decodedBytes = Base64.decode(sb.toString()); - return new XMLSignatureInput(decodedBytes); + XMLSignatureInput output = new XMLSignatureInput(decodedBytes); + output.setSecureValidation(secureValidation); + return output; } Base64.decode(sb.toString(), os); XMLSignatureInput output = new XMLSignatureInput((byte[])null); + output.setSecureValidation(secureValidation); output.setOutputStream(os); return output; } @@ -121,28 +124,34 @@ protected XMLSignatureInput enginePerformTransform( if (os == null) { byte[] base64Bytes = input.getBytes(); byte[] decodedBytes = Base64.decode(base64Bytes); - return new XMLSignatureInput(decodedBytes); + XMLSignatureInput output = new XMLSignatureInput(decodedBytes); + output.setSecureValidation(secureValidation); + return output; } if (input.isByteArray() || input.isNodeSet()) { Base64.decode(input.getBytes(), os); } else { Base64.decode(new BufferedInputStream(input.getOctetStreamReal()), os); } XMLSignatureInput output = new XMLSignatureInput((byte[])null); + output.setSecureValidation(secureValidation); output.setOutputStream(os); return output; } try { //Exceptional case there is current not text case testing this(Before it was a //a common case). - Document doc = XMLUtils.createDocumentBuilder(false).parse(input.getOctetStream()); + Document doc = + XMLUtils.createDocumentBuilder(false, secureValidation).parse(input.getOctetStream()); Element rootNode = doc.getDocumentElement(); StringBuilder sb = new StringBuilder(); traverseElement(rootNode, sb); byte[] decodedBytes = Base64.decode(sb.toString()); - return new XMLSignatureInput(decodedBytes); + XMLSignatureInput output = new XMLSignatureInput(decodedBytes); + output.setSecureValidation(secureValidation); + return output; } catch (ParserConfigurationException e) { throw new TransformationException("c14n.Canonicalizer.Exception",e); } catch (SAXException e) {
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14N11.java+1 −0 modified@@ -49,6 +49,7 @@ protected XMLSignatureInput enginePerformTransform( byte[] result = null; result = c14n.engineCanonicalize(input); XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); if (os != null) { output.setOutputStream(os); }
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14N11_WithComments.java+2 −1 modified@@ -50,7 +50,8 @@ protected XMLSignatureInput enginePerformTransform( byte[] result = null; result = c14n.engineCanonicalize(input); - XMLSignatureInput output = new XMLSignatureInput(result); + XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); if (os != null) { output.setOutputStream(os); }
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14NExclusive.java+1 −0 modified@@ -81,6 +81,7 @@ protected XMLSignatureInput enginePerformTransform( byte[] result = c14n.engineCanonicalize(input, inclusiveNamespaces); XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); if (os != null) { output.setOutputStream(os); }
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14NExclusiveWithComments.java+1 −0 modified@@ -83,6 +83,7 @@ protected XMLSignatureInput enginePerformTransform( } byte[] result = c14n.engineCanonicalize(input, inclusiveNamespaces); XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); return output; } catch (XMLSecurityException ex) {
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14N.java+1 −0 modified@@ -56,6 +56,7 @@ protected XMLSignatureInput enginePerformTransform( byte[] result = null; result = c14n.engineCanonicalize(input); XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); if (os != null) { output.setOutputStream(os); }
src/main/java/org/apache/xml/security/transforms/implementations/TransformC14NWithComments.java+2 −1 modified@@ -56,7 +56,8 @@ protected XMLSignatureInput enginePerformTransform( byte[] result = null; result = c14n.engineCanonicalize(input); - XMLSignatureInput output = new XMLSignatureInput(result); + XMLSignatureInput output = new XMLSignatureInput(result); + output.setSecureValidation(secureValidation); if (os != null) { output.setOutputStream(os); }
src/main/java/org/apache/xml/security/transforms/implementations/TransformXSLT.java+4 −1 modified@@ -138,12 +138,15 @@ protected XMLSignatureInput enginePerformTransform( ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); StreamResult outputTarget = new StreamResult(baos1); transformer.transform(xmlSource, outputTarget); - return new XMLSignatureInput(baos1.toByteArray()); + XMLSignatureInput output = new XMLSignatureInput(baos1.toByteArray()); + output.setSecureValidation(secureValidation); + return output; } StreamResult outputTarget = new StreamResult(baos); transformer.transform(xmlSource, outputTarget); XMLSignatureInput output = new XMLSignatureInput((byte[])null); + output.setSecureValidation(secureValidation); output.setOutputStream(baos); return output; } catch (XMLSecurityException ex) {
src/main/java/org/apache/xml/security/transforms/Transform.java+10 −0 modified@@ -74,6 +74,7 @@ public final class Transform extends SignatureElementProxy { new ConcurrentHashMap<String, Class<? extends TransformSpi>>(); private final TransformSpi transformSpi; + private boolean secureValidation; /** * Generates a Transform object that implements the specified @@ -301,6 +302,7 @@ public XMLSignatureInput performTransform( XMLSignatureInput result = null; try { + transformSpi.secureValidation = secureValidation; result = transformSpi.enginePerformTransform(input, os, this); } catch (ParserConfigurationException ex) { Object exArgs[] = { this.getURI(), "ParserConfigurationException" }; @@ -363,4 +365,12 @@ private TransformSpi initializeTransform(String algorithmURI, NodeList contextNo return newTransformSpi; } + public boolean isSecureValidation() { + return secureValidation; + } + + public void setSecureValidation(boolean secureValidation) { + this.secureValidation = secureValidation; + } + }
src/main/java/org/apache/xml/security/transforms/Transforms.java+1 −0 modified@@ -296,6 +296,7 @@ private void checkSecureValidation(Transform transform) throws TransformationExc "signature.Transform.ForbiddenTransform", exArgs ); } + transform.setSecureValidation(secureValidation); } /**
src/main/java/org/apache/xml/security/transforms/TransformSpi.java+2 −0 modified@@ -36,6 +36,8 @@ */ public abstract class TransformSpi { + protected boolean secureValidation; + /** * The mega method which MUST be implemented by the Transformation Algorithm. *
src/main/java/org/apache/xml/security/utils/resolver/implementations/ResolverAnonymous.java+3 −1 modified@@ -59,7 +59,9 @@ public ResolverAnonymous(InputStream is) { /** @inheritDoc */ @Override public XMLSignatureInput engineResolveURI(ResourceResolverContext context) { - return new XMLSignatureInput(inStream); + XMLSignatureInput input = new XMLSignatureInput(inStream); + input.setSecureValidation(context.secureValidation); + return input; } /**
src/main/java/org/apache/xml/security/utils/resolver/implementations/ResolverDirectHTTP.java+1 −0 modified@@ -151,6 +151,7 @@ public XMLSignatureInput engineResolveURI(ResourceResolverContext context) } XMLSignatureInput result = new XMLSignatureInput(baos.toByteArray()); + result.setSecureValidation(context.secureValidation); result.setSourceURI(uriNew.toString()); result.setMIMEType(mimeType);
src/main/java/org/apache/xml/security/utils/resolver/implementations/ResolverFragment.java+1 −0 modified@@ -103,6 +103,7 @@ public XMLSignatureInput engineResolveURI(ResourceResolverContext context) } XMLSignatureInput result = new XMLSignatureInput(selectedElem); + result.setSecureValidation(context.secureValidation); result.setExcludeComments(true); result.setMIMEType("text/xml");
src/main/java/org/apache/xml/security/utils/resolver/implementations/ResolverLocalFilesystem.java+1 −0 modified@@ -57,6 +57,7 @@ public XMLSignatureInput engineResolveURI(ResourceResolverContext context) ResolverLocalFilesystem.translateUriToFilename(uriNew.toString()); FileInputStream inputStream = new FileInputStream(fileName); XMLSignatureInput result = new XMLSignatureInput(inputStream); + result.setSecureValidation(context.secureValidation); result.setSourceURI(uriNew.toString());
src/main/java/org/apache/xml/security/utils/resolver/implementations/ResolverXPointer.java+1 −0 modified@@ -92,6 +92,7 @@ public XMLSignatureInput engineResolveURI(ResourceResolverContext context) } XMLSignatureInput result = new XMLSignatureInput(resultNode); + result.setSecureValidation(context.secureValidation); result.setMIMEType("text/xml"); if (context.baseUri != null && context.baseUri.length() > 0) {
src/main/java/org/apache/xml/security/utils/XMLUtils.java+9 −0 modified@@ -1027,8 +1027,17 @@ public static boolean protectAgainstWrappingAttack( } public static DocumentBuilder createDocumentBuilder(boolean validating) throws ParserConfigurationException { + return createDocumentBuilder(validating, true); + } + + public static DocumentBuilder createDocumentBuilder( + boolean validating, boolean disAllowDocTypeDeclarations + ) throws ParserConfigurationException { DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); + if (disAllowDocTypeDeclarations) { + dfactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + } dfactory.setValidating(validating); dfactory.setNamespaceAware(true);
src/test/java/javax/xml/crypto/test/dsig/JSRWrappingAttackTest.java+1 −1 modified@@ -56,7 +56,7 @@ public JSRWrappingAttackTest() { public void testWrappingAttack() throws Exception { String file = "manifestSignatureWrapping.xml"; - Document doc = XMLUtils.createDocumentBuilder(false).parse(new File(dir, file)); + Document doc = XMLUtils.createDocumentBuilder(false, false).parse(new File(dir, file)); Element sigElement = SignatureValidator.getSignatureElement(doc); if (sigElement == null) { throw new Exception("Couldn't find signature Element");
src/test/java/javax/xml/crypto/test/dsig/SignatureValidator.java+1 −1 modified@@ -54,7 +54,7 @@ public boolean validate(String fn, KeySelector ks) throws Exception { public DOMValidateContext getValidateContext(String fn, KeySelector ks) throws Exception { - Document doc = XMLUtils.createDocumentBuilder(false).parse(new File(dir, fn)); + Document doc = XMLUtils.createDocumentBuilder(false, false).parse(new File(dir, fn)); Element sigElement = getSignatureElement(doc); if (sigElement == null) { throw new Exception("Couldn't find signature Element");
src/test/java/javax/xml/crypto/test/dsig/TestUtils.java+1 −1 modified@@ -129,7 +129,7 @@ public static XMLValidateContext getXMLValidateContext(String type, String tag) throws Exception { if (type.equalsIgnoreCase("dom")) { - DocumentBuilder docBuilder = XMLUtils.createDocumentBuilder(false); + DocumentBuilder docBuilder = XMLUtils.createDocumentBuilder(false, false); Document doc = docBuilder.parse(input); if (tag == null) { return new DOMValidateContext
src/test/java/javax/xml/crypto/test/dsig/XMLSignatureFactoryTest.java+1 −1 modified@@ -153,7 +153,7 @@ public void setDefaultNamespacePrefix(String defPrefix) {} " for wrong inputs"); } - DocumentBuilder docBuilder = XMLUtils.createDocumentBuilder(false); + DocumentBuilder docBuilder = XMLUtils.createDocumentBuilder(false, false); String fs = System.getProperty("file.separator"); String base = System.getProperty("basedir") == null ? "./": System.getProperty("basedir"); File dir = new File(base + fs +
src/test/java/org/apache/xml/security/test/c14n/implementations/Canonicalizer11Test.java+1 −1 modified@@ -356,7 +356,7 @@ private boolean c14nAndCompare( ParserConfigurationException, CanonicalizationException, InvalidCanonicalizerException, TransformerException, XPathExpressionException { - DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(validating); + DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(validating, false); // throw away all warnings and errors documentBuilder.setErrorHandler(new IgnoreAllErrorHandler());
src/test/java/org/apache/xml/security/test/c14n/implementations/Canonicalizer20010315Test.java+2 −2 modified@@ -609,7 +609,7 @@ public void test37byNodeList() //String c14nURI = Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS; //boolean validating = true; - DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.xml.sax.EntityResolver resolver = new TestVectorResolver(); db.setEntityResolver(resolver); @@ -1038,7 +1038,7 @@ private boolean c14nAndCompare( ParserConfigurationException, CanonicalizationException, InvalidCanonicalizerException, TransformerException, XPathExpressionException { - DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(validating); + DocumentBuilder documentBuilder = XMLUtils.createDocumentBuilder(validating, false); // throw away all warnings and errors documentBuilder.setErrorHandler(new IgnoreAllErrorHandler());
src/test/java/org/apache/xml/security/test/c14n/implementations/ExclusiveC14NInteropTest.java+1 −1 modified@@ -126,7 +126,7 @@ private String t(String directory, String file) throws Exception { File f = new File(directory + "/" + file); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(f); Element sigElement =
src/test/java/org/apache/xml/security/test/interop/InteropTestBase.java+2 −2 modified@@ -59,7 +59,7 @@ public boolean verifyHMAC( String filename, ResourceResolverSpi resolver, boolean followManifests, byte[] hmacKey ) throws Exception { File f = new File(filename); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(new java.io.FileInputStream(f)); XPathFactory xpf = XPathFactory.newInstance(); @@ -93,7 +93,7 @@ public boolean verifyHMAC( public boolean verify(String filename, ResourceResolverSpi resolver, boolean followManifests) throws Exception { File f = new File(filename); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(f); XPathFactory xpf = XPathFactory.newInstance();
src/test/java/org/apache/xml/security/test/secure_val/ForbiddenAlgorithmTest.java+1 −1 modified@@ -70,7 +70,7 @@ private boolean readAndVerifySignature( File f = new File(directory + "/" + file); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(f); Element sigElement =
src/test/java/org/apache/xml/security/test/secure_val/WrappingAttackTest.java+2 −2 modified@@ -75,7 +75,7 @@ private boolean readAndVerifySignature( File f = new File(directory + "/" + file); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(f); Element sigElement = @@ -95,7 +95,7 @@ private boolean readAndVerifySignatureAndSetManifest( File f = new File(directory + "/" + file); - javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false); + javax.xml.parsers.DocumentBuilder db = XMLUtils.createDocumentBuilder(false, false); org.w3c.dom.Document doc = db.parse(f); Element sigElement =
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
27- santuario.apache.org/secadv.data/cve-2013-4517.txt.ascnvdVendor AdvisoryWEB
- secunia.com/advisories/55639nvdVendor Advisory
- github.com/advisories/GHSA-4p4w-6h54-g885ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2013-4517ghsaADVISORY
- packetstormsecurity.com/files/124554/Java-XML-Signature-Denial-Of-Service-Attack.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-0170.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-0171.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-0172.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-0195.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-1725.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-1726.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-1727.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2014-1728.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2015-0675.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2015-0850.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2015-0851.htmlnvdWEB
- seclists.org/fulldisclosure/2013/Dec/169nvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/89891nvdWEB
- github.com/apache/santuario-java/commit/a09b9042f7759d094f2d49f40fc7bcf145164b25ghsaWEB
- lists.apache.org/thread.html/680e6938b6412e26d5446054fd31de2011d33af11786b989127d1cc3@%3Ccommits.santuario.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r1c07a561426ec5579073046ad7f4207cdcef452bb3100abaf908e0cd@%3Ccommits.santuario.apache.org%3EghsaWEB
- www.tenable.com/security/tns-2018-15nvdWEB
- osvdb.org/101169nvd
- www.securityfocus.com/bid/64437nvd
- www.securitytracker.com/id/1029524nvd
- lists.apache.org/thread.html/680e6938b6412e26d5446054fd31de2011d33af11786b989127d1cc3%40%3Ccommits.santuario.apache.org%3Envd
- lists.apache.org/thread.html/r1c07a561426ec5579073046ad7f4207cdcef452bb3100abaf908e0cd%40%3Ccommits.santuario.apache.org%3Envd
News mentions
0No linked articles in our index yet.