1

I am trying to find a way to convert Document to String and found this XML Document to String? post here. But, I want to do the conversion without using TransformerFactory because of XXE Vulnerabilities and by using DocumentBuilderFactory only. I cannot upgrade to jdk8 because of other limitations.

I haven't had any luck so far with it; all the searches are returning the same code shown in the above link.

Is it possible to do this?

Community
  • 1
  • 1
iranichai
  • 363
  • 1
  • 6
  • 19

2 Answers2

0

This is difficult to do, but since your actual problem is the security vulnerability and not TransformerFactory, that may be a better way to go.

You should be able to configure TransformerFactory to ignore entities to prevent this sort of problem. See: Preventing XXE Injection

Another thing that may work for your security concerns is to use TransformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING). This should prevent the problems that you're worried about. See also this forum thread on coderanch.

Community
  • 1
  • 1
durron597
  • 31,968
  • 17
  • 99
  • 158
  • 1
    We can set FEATURE_SECURE_PROCESSING on TransformerFactory. But, we cannot set ACCESS_EXTERNAL_DTD, ACCESS_EXTERNAL_SCHEMA which are also needed. In JDK 8 by setting FEATURE_SECURE_PROCESSING will automatically set the other 2 features. JDK 6 and JDK 7 won't support these features which makes it incomplete solution. – iranichai May 01 '15 at 18:46
  • @iranichai they aren't included in Java 7? Documentation seems to suggest they are – durron597 May 01 '15 at 18:49
  • I see the exception 'javax.xml.transform.TransformerConfigurationException: Cannot set the feature 'http://javax.xml.XMLConstants/property/accessExternalDTD' on this TransformerFactory.' with jdk7 and found this http://stackoverflow.com/questions/27128578/set-feature-accessexternaldtd-in-transformerfactory – iranichai May 01 '15 at 19:31
  • Also doing search brings up this bug report http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8016153 which says the issue is fixed in jdk8 with an affected version of jdk7u40 – iranichai May 01 '15 at 19:33
0

Setting FEATURE_SECURE_PROCESSING may or may not help, depending on what implementation TransformerFactory.getInstance() actually returns.

For example in Java 7 with no additional XML libraries on classpath setting transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); does not help.

You can fix this by providing a Source other than StreamSource (which factory would need to parse using some settings that you do not control).

For example you can use StAXSource like this:

TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); // does not help in Java 7
Transformer transformer = transformerFactory.newTransformer();

// StreamSource is insecure by default:
// Source source = new StreamSource(new StringReader(xxeXml));

// Source configured to be secure:
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLEventReader xmlEventReader = xif.createXMLEventReader(new StringReader(xxeXml));
Source source = new StAXSource(xmlEventReader);

transformer.transform(
        source,
        new StreamResult(new ByteArrayOutputStream()));

Note the actual TrasformerFactory may not actually support StAXSource, so you need to test your code with the classpath as it would be on production. For example Saxon 9 (old one, I know) does not support StAXSource and the only clean way of "fixing" it that I know is to provide custom net.sf.saxon.Configuration instance.

Piotr Findeisen
  • 19,480
  • 2
  • 52
  • 82