Skip to content

Commit 0ffd484

Browse files
author
taylor.smock
committed
Fix an XPath injection issue
This isn't really an issue for JOSM, since we are only reading from public remote sources. git-svn-id: https://josm.openstreetmap.de/svn/trunk@19114 0c6e7542-c601-0410-84e7-c038aed88b3b
1 parent 08934e7 commit 0ffd484

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

src/org/openstreetmap/josm/tools/Mediawiki.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.net.URL;
77
import java.util.List;
88
import java.util.Optional;
9+
import java.util.concurrent.atomic.AtomicReference;
910
import java.util.function.BiConsumer;
1011
import java.util.stream.Collectors;
1112

@@ -59,22 +60,33 @@ public Optional<String> findExistingPage(List<String> pages)
5960
);
6061
final Document document = getDocument(url);
6162
final XPath xPath = XPathFactory.newInstance().newXPath();
62-
for (String page : distinctPages) {
63-
String normalized = xPath.evaluate("/api/query/normalized/n[@from='" + page + "']/@to", document);
64-
if (Utils.isEmpty(normalized)) {
65-
normalized = page;
63+
AtomicReference<String> normalized = new AtomicReference<>();
64+
AtomicReference<String> page = new AtomicReference<>();
65+
xPath.setXPathVariableResolver(v -> {
66+
if ("page".equals(v.getLocalPart())) {
67+
return page.get();
68+
} else if ("normalized".equals(v.getLocalPart())) {
69+
return normalized.get();
6670
}
67-
final Node node = (Node) xPath.evaluate("/api/query/pages/page[@title='" + normalized + "']", document, XPathConstants.NODE);
71+
throw new IllegalArgumentException();
72+
});
73+
for (String p : distinctPages) {
74+
page.set(p);
75+
normalized.set(xPath.evaluate("/api/query/normalized/n[@from=$page]/@to", document));
76+
if (Utils.isEmpty(normalized.get())) {
77+
normalized.set(page.get());
78+
}
79+
final Node node = (Node) xPath.evaluate("/api/query/pages/page[@title=$normalized]", document, XPathConstants.NODE);
6880
if (node != null
6981
&& node.getAttributes().getNamedItem("missing") == null
7082
&& node.getAttributes().getNamedItem("invalid") == null) {
71-
return Optional.of(page);
83+
return Optional.of(page.get());
7284
}
7385
}
7486
return Optional.empty();
7587
}
7688

77-
private Document getDocument(URL url) throws IOException, ParserConfigurationException, SAXException {
89+
private static Document getDocument(URL url) throws IOException, ParserConfigurationException, SAXException {
7890
final HttpClient.Response conn = HttpClient.create(url).connect();
7991
try (InputStream content = conn.getContent()) {
8092
return XmlUtils.parseSafeDOM(content);

0 commit comments

Comments
 (0)