I want to prevent a XXE attack in my project. It's old api project which runs on java 7 (no maven) and jboss-as-7 server. But during the execution i get the error: org.xml.sax.SAXNotRecognizedException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
org.xml.sax.SAXNotRecognizedException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
15:19:02,845 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at org.apache.xerces.jaxp.validation.ValidatorImpl.setProperty(ValidatorImpl.java:218)
15:19:02,846 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at com.uid.kua.web.KUARestController.authenticateAtAUA(KUARestController.java:118)
15:19:02,847 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
15:19:02,847 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
15:19:02,848 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
15:19:02,849 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) at java.lang.reflect.Method.invoke(Method.java:606)
I have searched about it and every forum has some different meaning to it saying it's a bug. I have not found any relevant solution for this exception. Please help. Thanks in advance.
Finally i resolved it. I am posting the answer in case this helps anyone. After going through online solutions i was unable to detect the main issue which was causing the above error. For xxe prevention we need some defined properties like: XMLConstants.ACCESS_EXTERNAL_DTD XMLConstants.ACCESS_EXTERNAL_SCHEMA
We need xerces and jaxp-api jars to pasrse xml and prevent xxe provided by the api's to resolve the xml by setting some above properties. Prior to JDK 7 these are already included in JDK 7 and above. So we don't need to import above jars in our project classpath.
In my case i was using jboss-as-7.1.1.Final as application server which also has it's own xerces jar (org.apache.xerces.). But java also comes with it's own xerces and jaxp implementation (com.sun.xerces.). So while deploying the war we get the above error as both these jars conflicts with each other where jboss loads it's own xerces jars.
Solution: We need to exclude the jboss xerces implementation by making changes in jboss/org/apache/xerces/main/modules.xml file. Comment out the lines as shown below:
> <module xmlns="urn:jboss:module:1.1" name="org.apache.xerces">
> <!--
> <resources>
> <resource-root path="xercesImpl-2.9.1-jbossas-1.jar"/>
> Insert resources here
> </resources>
> -->
> <dependencies>
> <module name="javax.api"/>
> </dependencies>
>
> </module>
Now deploy and run your application. Happy coding.
It seems that the attributes accessExternalDTD and accessExternalSchema were introduced in JAXP 1.5. However, Java EE 6 (and even still Java EE 8) only comes with JAXP 1.4.
In my case (running on WildFly 19 and AdoptOpenJDK 11) I was able to obtain the JDK's default instances of DocumentBuilderFactory and SchemaFactory by using their static newDefaultInstance() method which was introduced in Java 9. In Java 8 both classes also have a newInstance method where you can specify the class name, i.e. com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl and com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.
This solution avoids changing the JBoss modules.
javax.xml loads the implementation of certain Factory interfaces by going through a couple of options. First option is to configure a default implementation through a system property. For example:
javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema = com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory
javax.xml.parsers.DocumentBuilderFactory = com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
The second option is to use the jaxb.properties file which you have to include in your jre or jdk how you can do do that is described here: https://docs.oracle.com/javase/tutorial/jaxp/properties/usingProps.html
The third option is to add a file in META-INF/services of which the name should be the Factory interface that you want to define the implementation for and the file should contain the full package name + class name of the implementation. For example, you can add a file called javax.xml.parsers.DocumentBuilderFactory containing com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
The fourth option is to select the default implementation. In the case of Wildfly/Jboss they have included an org.apache.xerces implementation which only support JAXP 1.4. This means that it will select this implementation and that's why you get the error.
To find out which implementation is used for your specific function you can add a system property
jaxp.debug = 1
This property will enable debug mode for jaxp and you will see the following output:
JAXP: using thread context class loader (ModuleClassLoader for Module "deployment.css-private-build-1.0-SNAPSHOT.ear.css-private.war" from Service Module Loader) for search
JAXP: Looking up system property 'javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema'
JAXP: The value is 'com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory'
JAXP: createInstance(com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory)
JAXP: loaded com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory from (no code source)
JAXP: factory 'com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory' was found for http://www.w3.org/2001/XMLSchema
So before your error you will see the JAXP debug logging and then you should know which factory you have to provide an implementation for to get it to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With