lucene3/CVE-2017-12629.patch
2020-09-20 16:21:26 +08:00

139 lines
4.8 KiB
Diff

From 1853361e9f49f6b04aa5cd9ead85cf4620d4d249 Mon Sep 17 00:00:00 2001
From: Christine Poerschke <cpoerschke@apache.org>
Date: Fri, 13 Oct 2017 12:46:58 +0100
Subject: [PATCH] SOLR-11477: Disallow resolving of external entities in
Lucene
queryparser/xml/CoreParser and SolrCoreParser (defType=xmlparser or
{!xmlparser ...}) by default.
(Michael Stepankin, Olga Barinova, Uwe Schindler, Christine Poerschke)
---
.../apache/lucene/xmlparser/CoreParser.java | 74 +++++++++++++++----
1 file changed, 58 insertions(+), 16 deletions(-)
diff --git a/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/CoreParser.java b/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/CoreParser.java
index c84b90a..68c1529 100644
--- a/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/CoreParser.java
+++ b/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/CoreParser.java
@@ -1,9 +1,12 @@
package org.apache.lucene.xmlparser;
import java.io.InputStream;
+import java.util.Locale;
+import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.QueryParser;
@@ -11,6 +14,10 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.xmlparser.builders.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -123,7 +130,11 @@ public class CoreParser implements QueryBuilder
sqof.addBuilder("SpanNot",snot);
queryFactory.addBuilder("SpanNot",snot);
}
-
+
+ /**
+ * Parses the given stream as XML file and returns a {@link Query}.
+ * By default this disallows external entities for security reasons.
+ */
public Query parse(InputStream xmlStream) throws ParserException
{
return getQuery(parseXML(xmlStream).getDocumentElement());
@@ -138,28 +149,49 @@ public class CoreParser implements QueryBuilder
filterFactory.addBuilder(nodeName,builder);
}
- private static Document parseXML(InputStream pXmlFile) throws ParserException
- {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db = null;
+ /**
+ * Returns a SAX {@link EntityResolver} to be used by {@link DocumentBuilder}.
+ * By default this returns {@link #DISALLOW_EXTERNAL_ENTITY_RESOLVER}, which disallows the
+ * expansion of external entities (for security reasons). To restore legacy behavior,
+ * override this method to return {@code null}.
+ */
+ protected EntityResolver getEntityResolver() {
+ return DISALLOW_EXTERNAL_ENTITY_RESOLVER;
+ }
+
+ /**
+ * Subclass and override to return a SAX {@link ErrorHandler} to be used by {@link DocumentBuilder}.
+ * By default this returns {@code null} so no error handler is used.
+ * This method can be used to redirect XML parse errors/warnings to a custom logger.
+ */
+ protected ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ private Document parseXML(InputStream pXmlFile) throws ParserException {
+ final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setValidating(false);
try
{
- db = dbf.newDocumentBuilder();
- }
- catch (Exception se)
- {
- throw new ParserException("XML Parser configuration error", se);
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (ParserConfigurationException e) {
+ // ignore since all implementations are required to support the
+ // {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature
}
- org.w3c.dom.Document doc = null;
+ final DocumentBuilder db;
try
{
- doc = db.parse(pXmlFile);
+ db = dbf.newDocumentBuilder();
+ } catch (Exception se) {
+ throw new ParserException("XML Parser configuration error.", se);
}
- catch (Exception se)
- {
- throw new ParserException("Error parsing XML stream:" + se, se);
+ try {
+ db.setEntityResolver(getEntityResolver());
+ db.setErrorHandler(getErrorHandler());
+ return db.parse(pXmlFile);
+ } catch (Exception se) {
+ throw new ParserException("Error parsing XML stream: " + se, se);
}
- return doc;
}
@@ -167,4 +199,14 @@ public class CoreParser implements QueryBuilder
{
return queryFactory.getQuery(e);
}
+
+ public static final EntityResolver DISALLOW_EXTERNAL_ENTITY_RESOLVER = new EntityResolver() {
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
+ throw new SAXException(String.format(Locale.ENGLISH,
+ "External Entity resolving unsupported: publicId=\"%s\" systemId=\"%s\"",
+ publicId, systemId));
+ }
+ };
+
}
--
2.23.0