Skip to content

Commit 641325b

Browse files
committed
enable FEATURE_SECURE_PROCESSING for the XSLT processor
1 parent d75f212 commit 641325b

File tree

4 files changed

+113
-13
lines changed

4 files changed

+113
-13
lines changed

Diff for: src/changes/changes.xml

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
<body>
1010
<release version="2.70.0" date="Febuary xx, 2023" description="Bugfixes">
11+
<action type="fix" dev="rbri">
12+
Enable FEATURE_SECURE_PROCESSING for the XSLT processor.
13+
</action>
1114
<action type="add" dev="rbri">
1215
Document disabling of website certificate check in the FAQ.
1316
</action>

Diff for: src/main/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XSLTProcessor.java

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.HashMap;
2727
import java.util.Map;
2828

29+
import javax.xml.XMLConstants;
2930
import javax.xml.parsers.DocumentBuilderFactory;
3031
import javax.xml.transform.OutputKeys;
3132
import javax.xml.transform.Result;
@@ -128,6 +129,11 @@ private Object transform(final Node source) {
128129

129130
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
130131

132+
// By default, the JDK turns on FSP for DOM and SAX parsers and XML schema validators,
133+
// which sets a number of processing limits on the processors. Conversely, by default,
134+
// the JDK turns off FSP for transformers and XPath, which enables extension functions for XSLT and XPath.
135+
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
136+
131137
final SgmlPage page = sourceDomNode.getPage();
132138
if (page != null && page.getWebClient().getBrowserVersion()
133139
.hasFeature(JS_XSLT_TRANSFORM_INDENT)) {

Diff for: src/test/java/com/gargoylesoftware/htmlunit/ErrorOutputChecker.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ public class ErrorOutputChecker implements MethodRule {
4747
// Quercus
4848
Pattern.compile(".*com.caucho.quercus.servlet.QuercusServlet initImpl\r?\n"),
4949
Pattern.compile(".*QuercusServlet starting as QuercusServletImpl\r?\n"),
50-
Pattern.compile(".*Quercus finished initialization in \\d*ms\r?\n")
50+
Pattern.compile(".*Quercus finished initialization in \\d*ms\r?\n"),
51+
52+
// Xalan
53+
Pattern.compile("ERROR:\\s*'Use of the extension function "
54+
+ "'http://xml\\.apache\\.org/xalan/java/.*' "
55+
+ "is not allowed when the secure processing feature is set to true\\.'\r?\n"),
5156
};
5257

5358
/**

Diff for: src/test/java/com/gargoylesoftware/htmlunit/javascript/host/xml/XSLTProcessorTest.java

+98-12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.gargoylesoftware.htmlunit.WebDriverTestCase;
2424
import com.gargoylesoftware.htmlunit.junit.BrowserRunner;
2525
import com.gargoylesoftware.htmlunit.junit.BrowserRunner.Alerts;
26+
import com.gargoylesoftware.htmlunit.junit.BrowserRunner.HtmlUnitNYI;
2627
import com.gargoylesoftware.htmlunit.util.MimeType;
2728

2829
/**
@@ -38,28 +39,49 @@ public class XSLTProcessorTest extends WebDriverTestCase {
3839
* @throws Exception if the test fails
3940
*/
4041
@Test
41-
@Alerts("exception")
42+
@Alerts(DEFAULT = "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
43+
+ "<head></head><body> <h2>My CD Collection</h2> "
44+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul> </body></html>",
45+
FF = "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
46+
+ "<body><h2>My CD Collection</h2>"
47+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>",
48+
FF_ESR = "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
49+
+ "<body><h2>My CD Collection</h2>"
50+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>",
51+
IE = "exception")
52+
@HtmlUnitNYI(CHROME = "<html><body><h2>My CD Collection</h2>"
53+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>",
54+
EDGE = "<html><body><h2>My CD Collection</h2>"
55+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>",
56+
FF = "<html><body><h2>My CD Collection</h2>"
57+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>",
58+
FF_ESR = "<html><body><h2>My CD Collection</h2>"
59+
+ "<ul><li>Empire Burlesque (Bob Dylan)</li></ul></body></html>")
4260
public void test() throws Exception {
4361
final String html = "<html><head>\n"
4462
+ "<script>\n"
4563
+ LOG_TITLE_FUNCTION
64+
65+
+ " function createXmlDocument() {\n"
66+
+ " return document.implementation.createDocument('', '', null);\n"
67+
+ " }\n"
68+
69+
+ " function loadXMLDocument(url) {\n"
70+
+ " var xhttp = new XMLHttpRequest();\n"
71+
+ " xhttp.open('GET', url, false);\n"
72+
+ " xhttp.send();\n"
73+
+ " return xhttp.responseXML;\n"
74+
+ " }"
75+
4676
+ " function test() {\n"
4777
+ " try {\n"
48-
+ " var xmlDoc = createXmlDocument();\n"
49-
+ " xmlDoc.async = false;\n"
50-
+ " xmlDoc.load('" + URL_SECOND + "1');\n"
51-
52-
+ " var xslDoc;\n"
53-
+ " xslDoc = createXmlDocument();\n"
54-
+ " xslDoc.async = false;\n"
55-
+ " xslDoc.load('" + URL_SECOND + "2');\n"
78+
+ " var xmlDoc = loadXMLDocument('" + URL_SECOND + "1');\n"
79+
+ " var xslDoc = loadXMLDocument('" + URL_SECOND + "2');\n"
5680

5781
+ " var processor = new XSLTProcessor();\n"
5882
+ " processor.importStylesheet(xslDoc);\n"
5983
+ " var newDocument = processor.transformToDocument(xmlDoc);\n"
60-
+ " log(new XMLSerializer().serializeToString(newDocument.documentElement).length);\n"
61-
+ " newDocument = processor.transformToDocument(xmlDoc.documentElement);\n"
62-
+ " log(newDocument.documentElement);\n"
84+
+ " log(new XMLSerializer().serializeToString(newDocument.documentElement));\n"
6385
+ " } catch(e) { log('exception'); }\n"
6486
+ " }\n"
6587

@@ -199,4 +221,68 @@ public void browserDetection() throws Exception {
199221
+ "</body></html>";
200222
loadPageVerifyTitle2(html);
201223
}
224+
225+
/**
226+
* @throws Exception if the test fails
227+
*/
228+
@Test
229+
@Alerts(DEFAULT = {"preparation done", "null"},
230+
FF = {"preparation done", "exception"},
231+
FF_ESR = {"preparation done", "exception"},
232+
IE = "exception")
233+
@HtmlUnitNYI(CHROME = {"preparation done", "exception"},
234+
EDGE = {"preparation done", "exception"})
235+
public void testSecurity() throws Exception {
236+
final String html = "<html><head>\n"
237+
+ "<script>\n"
238+
+ LOG_TITLE_FUNCTION
239+
240+
+ " function createXmlDocument() {\n"
241+
+ " return document.implementation.createDocument('', '', null);\n"
242+
+ " }\n"
243+
244+
+ " function loadXMLDocument(url) {\n"
245+
+ " var xhttp = new XMLHttpRequest();\n"
246+
+ " xhttp.open('GET', url, false);\n"
247+
+ " xhttp.send();\n"
248+
+ " return xhttp.responseXML;\n"
249+
+ " }"
250+
251+
+ " function test() {\n"
252+
+ " try {\n"
253+
+ " var xmlDoc = loadXMLDocument('" + URL_SECOND + "1');\n"
254+
+ " var xslDoc = loadXMLDocument('" + URL_SECOND + "2');\n"
255+
256+
+ " var processor = new XSLTProcessor();\n"
257+
+ " processor.importStylesheet(xslDoc);\n"
258+
+ " log('preparation done');\n"
259+
+ " var newDocument = processor.transformToDocument(xmlDoc);\n"
260+
+ " log(newDocument);\n"
261+
+ " } catch(e) { log('exception'); }\n"
262+
+ " }\n"
263+
+ "</script></head>"
264+
+ "<body onload='test()'>\n"
265+
+ "</body></html>";
266+
267+
final String xml
268+
= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
269+
+ "<s></s>";
270+
271+
final String xsl
272+
= " <xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" "
273+
+ "xmlns:rt=\"http://xml.apache.org/xalan/java/java.lang.Runtime\" "
274+
+ "xmlns:ob=\"http://xml.apache.org/xalan/java/java.lang.Object\">\r\n"
275+
+ " <xsl:template match='/'>\n"
276+
+ " <xsl:variable name='rtobject' select='rt:getRuntime()'/>\n"
277+
+ " <xsl:variable name=\"rtString\" select=\"ob:toString($rtobject)\"/>\n"
278+
+ " <xsl:value-of select=\"$rtString\"/>\n"
279+
+ " </xsl:template>\r\n"
280+
+ " </xsl:stylesheet>";
281+
282+
final MockWebConnection conn = getMockWebConnection();
283+
conn.setResponse(new URL(URL_SECOND, "1"), xml, MimeType.TEXT_XML);
284+
conn.setResponse(new URL(URL_SECOND, "2"), xsl, MimeType.TEXT_XML);
285+
286+
loadPageVerifyTitle2(html);
287+
}
202288
}

0 commit comments

Comments
 (0)