Skip to content

Commit 25e059b

Browse files
committed
Added a check if the JAXP implementation understands features in JAXP
1.5. Concrete example is Xerces. Xerces does not support these features which will trigger an exception an cause the XML validation to always fail.
1 parent 39d5dac commit 25e059b

1 file changed

Lines changed: 40 additions & 3 deletions

File tree

  • core/src/main/java/com/onelogin/saml2/util

core/src/main/java/com/onelogin/saml2/util/Util.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import javax.xml.parsers.DocumentBuilder;
4141
import javax.xml.parsers.DocumentBuilderFactory;
4242
import javax.xml.parsers.ParserConfigurationException;
43+
import javax.xml.parsers.SAXParser;
44+
import javax.xml.parsers.SAXParserFactory;
4345
import javax.xml.transform.Source;
4446
import javax.xml.transform.dom.DOMSource;
4547
import javax.xml.validation.Schema;
@@ -99,10 +101,42 @@ public final class Util {
99101
public static final String UNIQUE_ID_PREFIX = "ONELOGIN_";
100102
public static final String RESPONSE_SIGNATURE_XPATH = "/samlp:Response/ds:Signature";
101103
public static final String ASSERTION_SIGNATURE_XPATH = "/samlp:Response/saml:Assertion/ds:Signature";
104+
/** Indicates if JAXP 1.5 support has been detected. */
105+
private static boolean JAXP_15_SUPPORTED = isJaxp15Supported();
102106

103107
private Util() {
104108
//not called
105109
}
110+
111+
/**
112+
* Method which uses the recommended way ( https://docs.oracle.com/javase/tutorial/jaxp/properties/error.html )
113+
* of checking if JAXP >= 1.5 options are supported. Needed if the project which uses this library also has
114+
* Xerces in it's classpath.
115+
*
116+
* If for whatever reason this method cannot determine if JAXP 1.5 properties are supported it will indicate the
117+
* options are supported. This way we don't accidentally disable configuration options.
118+
*
119+
* @return
120+
*/
121+
public static boolean isJaxp15Supported() {
122+
boolean supported = true;
123+
124+
try {
125+
SAXParserFactory spf = SAXParserFactory.newInstance();
126+
SAXParser parser = spf.newSAXParser();
127+
parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
128+
} catch (SAXException ex) {
129+
String err = ex.getMessage();
130+
if (err.contains("Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.")) {
131+
//expected, jaxp 1.5 not supported
132+
supported = false;
133+
}
134+
} catch (Exception e) {
135+
LOGGER.info("An exception occurred while trying to determine if JAXP 1.5 options are supported.", e);
136+
}
137+
138+
return supported;
139+
}
106140

107141
/**
108142
* This function load an XML string in a save way. Prevent XEE/XXE Attacks
@@ -218,9 +252,12 @@ public static boolean validateXML(Document xmlDocument, URL schemaUrl) {
218252

219253
Schema schema = SchemaFactory.loadFromUrl(schemaUrl);
220254
Validator validator = schema.newValidator();
221-
// Prevent XXE attacks
222-
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
223-
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
255+
256+
if (JAXP_15_SUPPORTED) {
257+
// Prevent XXE attacks
258+
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
259+
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
260+
}
224261

225262
XMLErrorAccumulatorHandler errorAcumulator = new XMLErrorAccumulatorHandler();
226263
validator.setErrorHandler(errorAcumulator);

0 commit comments

Comments
 (0)