|
12 | 12 | import java.io.File;
|
13 | 13 | import java.io.FileReader;
|
14 | 14 | import java.io.IOException;
|
| 15 | +import java.io.StringReader; |
15 | 16 | import java.util.Collections;
|
| 17 | +import java.util.HashMap; |
16 | 18 | import java.util.List;
|
17 | 19 | import java.util.logging.Level;
|
18 | 20 | import java.util.logging.Logger;
|
19 | 21 |
|
20 | 22 | import jenkins.security.MasterToSlaveCallable;
|
21 | 23 | import org.w3c.dom.*;
|
| 24 | + |
| 25 | +import javax.xml.XMLConstants; |
22 | 26 | import javax.xml.xpath.*;
|
23 | 27 | import javax.xml.parsers.*;
|
| 28 | + |
| 29 | +import org.xml.sax.EntityResolver; |
| 30 | +import org.xml.sax.InputSource; |
24 | 31 | import org.xml.sax.SAXException;
|
25 | 32 | import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
|
26 | 33 | import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
|
@@ -69,19 +76,66 @@ private static class ReadXML extends MasterToSlaveCallable<String, IOException>
|
69 | 76 | private String filename;
|
70 | 77 | private String xpathexpression;
|
71 | 78 |
|
| 79 | + private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl"; |
| 80 | + private static final String EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities"; |
| 81 | + private static final String EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities"; |
| 82 | + private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; |
| 83 | + |
72 | 84 | public ReadXML(String root, String filename, String xpath){
|
73 | 85 | this.root=root;
|
74 | 86 | this.filename=filename;
|
75 | 87 | this.xpathexpression=xpath;
|
76 | 88 | }
|
77 | 89 |
|
78 |
| - public String call() throws IOException { |
| 90 | + private DocumentBuilderFactory createFactory() { |
| 91 | + DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); |
| 92 | + HashMap<String, Boolean> features = new HashMap<>(); |
| 93 | + features.put(DISALLOW_DOCTYPE_DECL, true); |
| 94 | + features.put(EXTERNAL_GENERAL_ENTITIES, false); |
| 95 | + features.put(EXTERNAL_PARAMETER_ENTITIES, false); |
| 96 | + features.put(LOAD_EXTERNAL_DTD, false); |
| 97 | + |
| 98 | + for(String feature : features.keySet()) { |
| 99 | + try { |
| 100 | + dFactory.setFeature(feature, features.get(feature)); |
| 101 | + } catch(ParserConfigurationException e) { |
| 102 | + LOGGER.log(Level.INFO, "Could not enable/disable feature: " + feature); |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + HashMap<String, String> attributes = new HashMap<>(); |
| 107 | + attributes.put(XMLConstants.FEATURE_SECURE_PROCESSING, "true"); |
| 108 | + attributes.put(XMLConstants.ACCESS_EXTERNAL_DTD, ""); |
| 109 | + attributes.put(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); |
| 110 | + attributes.put(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); |
| 111 | + for(String attribute : attributes.keySet()) { |
| 112 | + try { |
| 113 | + dFactory.setAttribute(attribute, attributes.get(attribute)); |
| 114 | + } catch(IllegalArgumentException e) { |
| 115 | + LOGGER.log(Level.INFO, "Could not set attribute: " + attribute); |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + dFactory.setXIncludeAware(false); |
| 120 | + dFactory.setExpandEntityReferences(false); |
| 121 | + return dFactory; |
| 122 | + } |
| 123 | + |
| 124 | + public String call() { |
79 | 125 | File file = new File(root, filename);
|
80 | 126 | String result = "";
|
81 | 127 | if (file.exists()) {
|
82 | 128 | try {
|
83 |
| - DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); |
| 129 | + DocumentBuilderFactory dFactory = createFactory(); |
| 130 | + |
| 131 | + EntityResolver noop = new EntityResolver() { |
| 132 | + @Override |
| 133 | + public InputSource resolveEntity(String publicId, String systemId) { |
| 134 | + return new InputSource(new StringReader("")); |
| 135 | + } |
| 136 | + }; |
84 | 137 | DocumentBuilder builder = dFactory.newDocumentBuilder();
|
| 138 | + builder.setEntityResolver(noop); |
85 | 139 | Document doc = builder.parse(file.toString());
|
86 | 140 | XPath xpathInstance = XPathFactory.newInstance().newXPath();
|
87 | 141 | XPathExpression expr = xpathInstance.compile(xpathexpression);
|
|
0 commit comments