mirror of https://github.com/apache/jmeter.git
Bug 63793 - Fix unsecure XML Parsing
This commit is contained in:
parent
8323941eb8
commit
d467f5368f
|
|
@ -22,6 +22,8 @@ import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
|
||||||
import org.apache.jmeter.samplers.SampleResult;
|
import org.apache.jmeter.samplers.SampleResult;
|
||||||
import org.apache.jmeter.testelement.AbstractTestElement;
|
import org.apache.jmeter.testelement.AbstractTestElement;
|
||||||
import org.apache.jmeter.testelement.ThreadListener;
|
import org.apache.jmeter.testelement.ThreadListener;
|
||||||
|
|
@ -46,7 +48,9 @@ public class XMLAssertion extends AbstractTestElement implements Serializable, A
|
||||||
@Override
|
@Override
|
||||||
protected XMLReader initialValue() {
|
protected XMLReader initialValue() {
|
||||||
try {
|
try {
|
||||||
return XMLReaderFactory.createXMLReader();
|
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||||
|
reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
return reader;
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
log.error("Error initializing XMLReader in XMLAssertion", e);
|
log.error("Error initializing XMLReader in XMLAssertion", e);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
@ -102,7 +103,7 @@ public class XMLSchemaAssertion extends AbstractTestElement implements Serializa
|
||||||
parserFactory.setNamespaceAware(true);
|
parserFactory.setNamespaceAware(true);
|
||||||
parserFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
parserFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
||||||
parserFactory.setAttribute(JAXP_SCHEMA_SOURCE, xsdFileName);
|
parserFactory.setAttribute(JAXP_SCHEMA_SOURCE, xsdFileName);
|
||||||
|
parserFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
// create a parser:
|
// create a parser:
|
||||||
DocumentBuilder parser = parserFactory.newDocumentBuilder();
|
DocumentBuilder parser = parserFactory.newDocumentBuilder();
|
||||||
parser.setErrorHandler(new SAXErrorHandler(result));
|
parser.setErrorHandler(new SAXErrorHandler(result));
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.MenuElement;
|
import javax.swing.MenuElement;
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
|
@ -69,6 +70,7 @@ public class SchematicView extends AbstractAction implements MenuCreator {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
TransformerFactory factory = TransformerFactory.newInstance(
|
TransformerFactory factory = TransformerFactory.newInstance(
|
||||||
"net.sf.saxon.BasicTransformerFactory", Thread.currentThread().getContextClassLoader());
|
"net.sf.saxon.BasicTransformerFactory", Thread.currentThread().getContextClassLoader());
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
Source xslt;
|
Source xslt;
|
||||||
if (!StringUtils.isEmpty(DEFAULT_XSL_FILE)) {
|
if (!StringUtils.isEmpty(DEFAULT_XSL_FILE)) {
|
||||||
log.info("Will use file {} for Schematic View generation", DEFAULT_XSL_FILE);
|
log.info("Will use file {} for Schematic View generation", DEFAULT_XSL_FILE);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
@ -167,6 +168,7 @@ public class TemplateManager {
|
||||||
dbf.setNamespaceAware(true);
|
dbf.setNamespaceAware(true);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
DocumentBuilder bd = dbf.newDocumentBuilder();
|
DocumentBuilder bd = dbf.newDocumentBuilder();
|
||||||
bd.setEntityResolver(new DefaultEntityResolver());
|
bd.setEntityResolver(new DefaultEntityResolver());
|
||||||
LoggingErrorHandler errorHandler = new LoggingErrorHandler(log, file);
|
LoggingErrorHandler errorHandler = new LoggingErrorHandler(log, file);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
@ -65,6 +66,9 @@ import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
|
||||||
import net.sf.saxon.s9api.Processor;
|
import net.sf.saxon.s9api.Processor;
|
||||||
import net.sf.saxon.s9api.SaxonApiException;
|
import net.sf.saxon.s9api.SaxonApiException;
|
||||||
import net.sf.saxon.s9api.XPathExecutable;
|
import net.sf.saxon.s9api.XPathExecutable;
|
||||||
|
|
@ -72,9 +76,6 @@ import net.sf.saxon.s9api.XPathSelector;
|
||||||
import net.sf.saxon.s9api.XdmItem;
|
import net.sf.saxon.s9api.XdmItem;
|
||||||
import net.sf.saxon.s9api.XdmNode;
|
import net.sf.saxon.s9api.XdmNode;
|
||||||
import net.sf.saxon.s9api.XdmValue;
|
import net.sf.saxon.s9api.XdmValue;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
|
||||||
/**
|
/**
|
||||||
* This class provides a few utility methods for dealing with XML/XPath.
|
* This class provides a few utility methods for dealing with XML/XPath.
|
||||||
*/
|
*/
|
||||||
|
|
@ -115,12 +116,13 @@ public class XPathUtil {
|
||||||
* @return javax.xml.parsers.DocumentBuilderFactory
|
* @return javax.xml.parsers.DocumentBuilderFactory
|
||||||
*/
|
*/
|
||||||
private static synchronized DocumentBuilderFactory makeDocumentBuilderFactory(boolean validate, boolean whitespace,
|
private static synchronized DocumentBuilderFactory makeDocumentBuilderFactory(boolean validate, boolean whitespace,
|
||||||
boolean namespace) {
|
boolean namespace) throws ParserConfigurationException {
|
||||||
if (XPathUtil.documentBuilderFactory == null || documentBuilderFactory.isValidating() != validate
|
if (XPathUtil.documentBuilderFactory == null || documentBuilderFactory.isValidating() != validate
|
||||||
|| documentBuilderFactory.isNamespaceAware() != namespace
|
|| documentBuilderFactory.isNamespaceAware() != namespace
|
||||||
|| documentBuilderFactory.isIgnoringElementContentWhitespace() != whitespace) {
|
|| documentBuilderFactory.isIgnoringElementContentWhitespace() != whitespace) {
|
||||||
// configure the document builder factory
|
// configure the document builder factory
|
||||||
documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
documentBuilderFactory.setValidating(validate);
|
documentBuilderFactory.setValidating(validate);
|
||||||
documentBuilderFactory.setNamespaceAware(namespace);
|
documentBuilderFactory.setNamespaceAware(namespace);
|
||||||
documentBuilderFactory.setIgnoringElementContentWhitespace(whitespace);
|
documentBuilderFactory.setIgnoringElementContentWhitespace(whitespace);
|
||||||
|
|
@ -309,7 +311,9 @@ public class XPathUtil {
|
||||||
private static String getNodeContent(Node node) {
|
private static String getNodeContent(Node node) {
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
try {
|
try {
|
||||||
Transformer t = TransformerFactory.newInstance().newTransformer();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
Transformer t = factory.newTransformer();
|
||||||
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
t.transform(new DOMSource(node), new StreamResult(sw));
|
t.transform(new DOMSource(node), new StreamResult(sw));
|
||||||
} catch (TransformerException e) {
|
} catch (TransformerException e) {
|
||||||
|
|
@ -731,7 +735,9 @@ public class XPathUtil {
|
||||||
*/
|
*/
|
||||||
public static String formatXml(String xml){
|
public static String formatXml(String xml){
|
||||||
try {
|
try {
|
||||||
Transformer serializer= TransformerFactory.newInstance().newTransformer();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
Transformer serializer= factory.newTransformer();
|
||||||
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
|
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||||
Source xmlSource = new SAXSource(new InputSource(new StringReader(xml)));
|
Source xmlSource = new SAXSource(new InputSource(new StringReader(xml)));
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
@ -67,7 +68,9 @@ public class XPathFileContainer {
|
||||||
NodeList nl = null;
|
NodeList nl = null;
|
||||||
try ( FileInputStream fis = new FileInputStream(fileName);
|
try ( FileInputStream fis = new FileInputStream(fileName);
|
||||||
BufferedInputStream bis = new BufferedInputStream(fis) ){
|
BufferedInputStream bis = new BufferedInputStream(fis) ){
|
||||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
nl = XPathUtil.selectNodeList(builder.parse(bis), xpath);
|
nl = XPathUtil.selectNodeList(builder.parse(bis), xpath);
|
||||||
if(log.isDebugEnabled()) {
|
if(log.isDebugEnabled()) {
|
||||||
log.debug("found {}", nl.getLength());
|
log.debug("found {}", nl.getLength());
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParser;
|
import javax.xml.parsers.SAXParser;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
@ -237,6 +238,7 @@ public class DefaultSamplerCreator extends AbstractSamplerCreator {
|
||||||
private static boolean isPotentialXml(String postData) {
|
private static boolean isPotentialXml(String postData) {
|
||||||
try {
|
try {
|
||||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||||
|
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
SAXParser saxParser = spf.newSAXParser();
|
SAXParser saxParser = spf.newSAXParser();
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
ErrorDetectionHandler detectionHandler =
|
ErrorDetectionHandler detectionHandler =
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ class ObjectMessageRenderer implements MessageRenderer<Serializable> {
|
||||||
/** Try to determine encoding based on XML prolog, if none <code>null</code> is returned. **/
|
/** Try to determine encoding based on XML prolog, if none <code>null</code> is returned. **/
|
||||||
protected String findEncoding(String filename) {
|
protected String findEncoding(String filename) {
|
||||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
|
||||||
try (FileInputStream input = new FileInputStream(filename)) {
|
try (FileInputStream input = new FileInputStream(filename)) {
|
||||||
XMLStreamReader reader = factory.createXMLStreamReader(input);
|
XMLStreamReader reader = factory.createXMLStreamReader(input);
|
||||||
return reader.getEncoding();
|
return reader.getEncoding();
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,16 @@ to view the last release notes of version 5.1.1.
|
||||||
<ul>
|
<ul>
|
||||||
<li>HTTP(S) Test Script Recorder now appends number at end of names, while previously it added it at beginning. See <bugzilla>63450</bugzilla></li>
|
<li>HTTP(S) Test Script Recorder now appends number at end of names, while previously it added it at beginning. See <bugzilla>63450</bugzilla></li>
|
||||||
<li>When using XPath Assertion with an XPath expression returning a boolean, <code>True if nothing matches</code> had no effect and always returned true, see <bugzilla>63455</bugzilla></li>
|
<li>When using XPath Assertion with an XPath expression returning a boolean, <code>True if nothing matches</code> had no effect and always returned true, see <bugzilla>63455</bugzilla></li>
|
||||||
|
<li>XML parsing now refuses unsecure XML, this has impacts on the following features:
|
||||||
|
<ul>
|
||||||
|
<li>XMLAssertion</li>
|
||||||
|
<li>XMLSchemAssertion</li>
|
||||||
|
<li>XPath function</li>
|
||||||
|
<li>XPath 1 & 2 Extractors</li>
|
||||||
|
<li>XPath 1 & 2 Assertions</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- =================== Improvements =================== -->
|
<!-- =================== Improvements =================== -->
|
||||||
|
|
||||||
|
|
@ -234,6 +244,7 @@ to view the last release notes of version 5.1.1.
|
||||||
<li><bug>63751</bug>Correct a typo in Chinese translations. Reported by Jinliang Wang (wjl31802 at 126.com)</li>
|
<li><bug>63751</bug>Correct a typo in Chinese translations. Reported by Jinliang Wang (wjl31802 at 126.com)</li>
|
||||||
<li><bug>63723</bug>Distributed testing: JMeter master ends distributed test though some threads still are active</li>
|
<li><bug>63723</bug>Distributed testing: JMeter master ends distributed test though some threads still are active</li>
|
||||||
<li><bug>63614</bug>Distributed testing: Unable to generate Dashboard report at end of load test</li>
|
<li><bug>63614</bug>Distributed testing: Unable to generate Dashboard report at end of load test</li>
|
||||||
|
<li><bug>63793</bug>Fix unsecure XML Parsing</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- =================== Thanks =================== -->
|
<!-- =================== Thanks =================== -->
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue