Skip to content

Commit 004319f

Browse files
slidedaniel-beck
authored andcommitted
Fix SECURITY-1399
1 parent 354f4fa commit 004319f

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

src/main/java/org/jenkinsci/plugins/tokenmacro/impl/XmlFileMacro.java

+56-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,22 @@
1212
import java.io.File;
1313
import java.io.FileReader;
1414
import java.io.IOException;
15+
import java.io.StringReader;
1516
import java.util.Collections;
17+
import java.util.HashMap;
1618
import java.util.List;
1719
import java.util.logging.Level;
1820
import java.util.logging.Logger;
1921

2022
import jenkins.security.MasterToSlaveCallable;
2123
import org.w3c.dom.*;
24+
25+
import javax.xml.XMLConstants;
2226
import javax.xml.xpath.*;
2327
import javax.xml.parsers.*;
28+
29+
import org.xml.sax.EntityResolver;
30+
import org.xml.sax.InputSource;
2431
import org.xml.sax.SAXException;
2532
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
2633
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
@@ -69,19 +76,66 @@ private static class ReadXML extends MasterToSlaveCallable<String, IOException>
6976
private String filename;
7077
private String xpathexpression;
7178

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+
7284
public ReadXML(String root, String filename, String xpath){
7385
this.root=root;
7486
this.filename=filename;
7587
this.xpathexpression=xpath;
7688
}
7789

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() {
79125
File file = new File(root, filename);
80126
String result = "";
81127
if (file.exists()) {
82128
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+
};
84137
DocumentBuilder builder = dFactory.newDocumentBuilder();
138+
builder.setEntityResolver(noop);
85139
Document doc = builder.parse(file.toString());
86140
XPath xpathInstance = XPathFactory.newInstance().newXPath();
87141
XPathExpression expr = xpathInstance.compile(xpathexpression);

0 commit comments

Comments
 (0)