Skip to content

Commit

Permalink
Fix an XPath injection issue
Browse files Browse the repository at this point in the history
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
  • Loading branch information
taylor.smock committed Jun 18, 2024
1 parent 08934e7 commit 0ffd484
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/org/openstreetmap/josm/tools/Mediawiki.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -59,22 +60,33 @@ public Optional<String> findExistingPage(List<String> pages)
);
final Document document = getDocument(url);
final XPath xPath = XPathFactory.newInstance().newXPath();
for (String page : distinctPages) {
String normalized = xPath.evaluate("/api/query/normalized/n[@from='" + page + "']/@to", document);
if (Utils.isEmpty(normalized)) {
normalized = page;
AtomicReference<String> normalized = new AtomicReference<>();
AtomicReference<String> page = new AtomicReference<>();
xPath.setXPathVariableResolver(v -> {
if ("page".equals(v.getLocalPart())) {
return page.get();
} else if ("normalized".equals(v.getLocalPart())) {
return normalized.get();
}
final Node node = (Node) xPath.evaluate("/api/query/pages/page[@title='" + normalized + "']", document, XPathConstants.NODE);
throw new IllegalArgumentException();
});
for (String p : distinctPages) {
page.set(p);
normalized.set(xPath.evaluate("/api/query/normalized/n[@from=$page]/@to", document));
if (Utils.isEmpty(normalized.get())) {
normalized.set(page.get());
}
final Node node = (Node) xPath.evaluate("/api/query/pages/page[@title=$normalized]", document, XPathConstants.NODE);
if (node != null
&& node.getAttributes().getNamedItem("missing") == null
&& node.getAttributes().getNamedItem("invalid") == null) {
return Optional.of(page);
return Optional.of(page.get());
}
}
return Optional.empty();
}

private Document getDocument(URL url) throws IOException, ParserConfigurationException, SAXException {
private static Document getDocument(URL url) throws IOException, ParserConfigurationException, SAXException {
final HttpClient.Response conn = HttpClient.create(url).connect();
try (InputStream content = conn.getContent()) {
return XmlUtils.parseSafeDOM(content);
Expand Down

0 comments on commit 0ffd484

Please sign in to comment.