|
40 | 40 | import javax.xml.parsers.DocumentBuilder; |
41 | 41 | import javax.xml.parsers.DocumentBuilderFactory; |
42 | 42 | import javax.xml.parsers.ParserConfigurationException; |
| 43 | +import javax.xml.parsers.SAXParser; |
| 44 | +import javax.xml.parsers.SAXParserFactory; |
43 | 45 | import javax.xml.transform.Source; |
44 | 46 | import javax.xml.transform.dom.DOMSource; |
45 | 47 | import javax.xml.validation.Schema; |
@@ -99,10 +101,42 @@ public final class Util { |
99 | 101 | public static final String UNIQUE_ID_PREFIX = "ONELOGIN_"; |
100 | 102 | public static final String RESPONSE_SIGNATURE_XPATH = "/samlp:Response/ds:Signature"; |
101 | 103 | 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(); |
102 | 106 |
|
103 | 107 | private Util() { |
104 | 108 | //not called |
105 | 109 | } |
| 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 | + } |
106 | 140 |
|
107 | 141 | /** |
108 | 142 | * 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) { |
218 | 252 |
|
219 | 253 | Schema schema = SchemaFactory.loadFromUrl(schemaUrl); |
220 | 254 | 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 | + } |
224 | 261 |
|
225 | 262 | XMLErrorAccumulatorHandler errorAcumulator = new XMLErrorAccumulatorHandler(); |
226 | 263 | validator.setErrorHandler(errorAcumulator); |
|
0 commit comments