|
|
fa9b16 |
From 039b3453d17bb5666d4b7a4eacc6a014703416c7 Mon Sep 17 00:00:00 2001
|
|
|
fa9b16 |
From: Chris Kelley <ckelley@redhat.com>
|
|
|
fa9b16 |
Date: Fri, 10 Jun 2022 17:25:07 +0100
|
|
|
fa9b16 |
Subject: [PATCH] Disable access to external entities when parsing XML
|
|
|
fa9b16 |
|
|
|
fa9b16 |
This reduces the vulnerability of XML parsers to XXE (XML external
|
|
|
fa9b16 |
entity) injection.
|
|
|
fa9b16 |
|
|
|
fa9b16 |
The best way to prevent XXE is to stop using XML altogether, which we do
|
|
|
fa9b16 |
plan to do. Until that happens I consider it worthwhile to tighten the
|
|
|
fa9b16 |
security here though.
|
|
|
fa9b16 |
---
|
|
|
fa9b16 |
.../cms/servlet/csadmin/SecurityDomainProcessor.java | 6 +++++-
|
|
|
fa9b16 |
.../main/java/com/netscape/cmscore/apps/ServerXml.java | 1 +
|
|
|
fa9b16 |
.../main/java/com/netscape/cmsutil/xml/XMLObject.java | 9 +++++++++
|
|
|
fa9b16 |
.../src/test/java/com/netscape/test/TestListener.java | 5 ++++-
|
|
|
fa9b16 |
4 files changed, 19 insertions(+), 2 deletions(-)
|
|
|
fa9b16 |
|
|
|
fa9b16 |
diff --git a/base/server/src/main/java/com/netscape/cms/servlet/csadmin/SecurityDomainProcessor.java b/base/server/src/main/java/com/netscape/cms/servlet/csadmin/SecurityDomainProcessor.java
|
|
|
fa9b16 |
index bdd485e89a..07fae1ad50 100644
|
|
|
fa9b16 |
--- a/base/server/src/main/java/com/netscape/cms/servlet/csadmin/SecurityDomainProcessor.java
|
|
|
fa9b16 |
+++ b/base/server/src/main/java/com/netscape/cms/servlet/csadmin/SecurityDomainProcessor.java
|
|
|
fa9b16 |
@@ -24,6 +24,7 @@ import java.util.Enumeration;
|
|
|
fa9b16 |
import java.util.Locale;
|
|
|
fa9b16 |
import java.util.Vector;
|
|
|
fa9b16 |
|
|
|
fa9b16 |
+import javax.xml.XMLConstants;
|
|
|
fa9b16 |
import javax.xml.parsers.ParserConfigurationException;
|
|
|
fa9b16 |
import javax.xml.transform.OutputKeys;
|
|
|
fa9b16 |
import javax.xml.transform.Transformer;
|
|
|
fa9b16 |
@@ -697,7 +698,10 @@ public class SecurityDomainProcessor extends Processor {
|
|
|
fa9b16 |
XMLObject xmlObject = convertDomainInfoToXMLObject(before);
|
|
|
fa9b16 |
Document document = xmlObject.getDocument();
|
|
|
fa9b16 |
|
|
|
fa9b16 |
- Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
|
|
fa9b16 |
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
|
|
fa9b16 |
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
fa9b16 |
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
fa9b16 |
+ Transformer transformer = transformerFactory.newTransformer();
|
|
|
fa9b16 |
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
|
fa9b16 |
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
|
|
fa9b16 |
|
|
|
fa9b16 |
diff --git a/base/server/src/main/java/com/netscape/cmscore/apps/ServerXml.java b/base/server/src/main/java/com/netscape/cmscore/apps/ServerXml.java
|
|
|
fa9b16 |
index 2a02d722a1..d9ac572747 100644
|
|
|
fa9b16 |
--- a/base/server/src/main/java/com/netscape/cmscore/apps/ServerXml.java
|
|
|
fa9b16 |
+++ b/base/server/src/main/java/com/netscape/cmscore/apps/ServerXml.java
|
|
|
fa9b16 |
@@ -41,6 +41,7 @@ public class ServerXml {
|
|
|
fa9b16 |
ServerXml serverXml = new ServerXml();
|
|
|
fa9b16 |
|
|
|
fa9b16 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
|
fa9b16 |
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
|
fa9b16 |
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
|
fa9b16 |
Document document = builder.parse(filename);
|
|
|
fa9b16 |
|
|
|
fa9b16 |
diff --git a/base/util/src/main/java/com/netscape/cmsutil/xml/XMLObject.java b/base/util/src/main/java/com/netscape/cmsutil/xml/XMLObject.java
|
|
|
fa9b16 |
index 81fdbf4b2e..1043bcb477 100644
|
|
|
fa9b16 |
--- a/base/util/src/main/java/com/netscape/cmsutil/xml/XMLObject.java
|
|
|
fa9b16 |
+++ b/base/util/src/main/java/com/netscape/cmsutil/xml/XMLObject.java
|
|
|
fa9b16 |
@@ -25,6 +25,7 @@ import java.io.OutputStream;
|
|
|
fa9b16 |
import java.io.StringWriter;
|
|
|
fa9b16 |
import java.util.Vector;
|
|
|
fa9b16 |
|
|
|
fa9b16 |
+import javax.xml.XMLConstants;
|
|
|
fa9b16 |
import javax.xml.parsers.DocumentBuilder;
|
|
|
fa9b16 |
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
fa9b16 |
import javax.xml.parsers.ParserConfigurationException;
|
|
|
fa9b16 |
@@ -56,6 +57,7 @@ public class XMLObject {
|
|
|
fa9b16 |
public XMLObject(InputStream s)
|
|
|
fa9b16 |
throws SAXException, IOException, ParserConfigurationException {
|
|
|
fa9b16 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
|
fa9b16 |
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
|
fa9b16 |
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
|
|
fa9b16 |
mDoc = docBuilder.parse(s);
|
|
|
fa9b16 |
}
|
|
|
fa9b16 |
@@ -63,6 +65,7 @@ public class XMLObject {
|
|
|
fa9b16 |
public XMLObject(File f)
|
|
|
fa9b16 |
throws SAXException, IOException, ParserConfigurationException {
|
|
|
fa9b16 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
|
fa9b16 |
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
|
fa9b16 |
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
|
|
fa9b16 |
mDoc = docBuilder.parse(f);
|
|
|
fa9b16 |
}
|
|
|
fa9b16 |
@@ -159,6 +162,8 @@ public class XMLObject {
|
|
|
fa9b16 |
public byte[] toByteArray() throws TransformerConfigurationException, TransformerException {
|
|
|
fa9b16 |
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
fa9b16 |
TransformerFactory tranFactory = TransformerFactory.newInstance();
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
fa9b16 |
Transformer aTransformer = tranFactory.newTransformer();
|
|
|
fa9b16 |
Source src = new DOMSource(mDoc);
|
|
|
fa9b16 |
Result dest = new StreamResult(bos);
|
|
|
fa9b16 |
@@ -169,6 +174,8 @@ public class XMLObject {
|
|
|
fa9b16 |
public void output(OutputStream os)
|
|
|
fa9b16 |
throws TransformerConfigurationException, TransformerException {
|
|
|
fa9b16 |
TransformerFactory tranFactory = TransformerFactory.newInstance();
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
fa9b16 |
Transformer aTransformer = tranFactory.newTransformer();
|
|
|
fa9b16 |
Source src = new DOMSource(mDoc);
|
|
|
fa9b16 |
Result dest = new StreamResult(os);
|
|
|
fa9b16 |
@@ -177,6 +184,8 @@ public class XMLObject {
|
|
|
fa9b16 |
|
|
|
fa9b16 |
public String toXMLString() throws TransformerConfigurationException, TransformerException {
|
|
|
fa9b16 |
TransformerFactory tranFactory = TransformerFactory.newInstance();
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
fa9b16 |
Transformer transformer = tranFactory.newTransformer();
|
|
|
fa9b16 |
Source src = new DOMSource(mDoc);
|
|
|
fa9b16 |
StreamResult dest = new StreamResult(new StringWriter());
|
|
|
fa9b16 |
diff --git a/base/util/src/test/java/com/netscape/test/TestListener.java b/base/util/src/test/java/com/netscape/test/TestListener.java
|
|
|
fa9b16 |
index 3181d53dc8..ac5d6e0f42 100644
|
|
|
fa9b16 |
--- a/base/util/src/test/java/com/netscape/test/TestListener.java
|
|
|
fa9b16 |
+++ b/base/util/src/test/java/com/netscape/test/TestListener.java
|
|
|
fa9b16 |
@@ -10,6 +10,7 @@ import java.text.SimpleDateFormat;
|
|
|
fa9b16 |
import java.util.Date;
|
|
|
fa9b16 |
import java.util.TimeZone;
|
|
|
fa9b16 |
|
|
|
fa9b16 |
+import javax.xml.XMLConstants;
|
|
|
fa9b16 |
import javax.xml.parsers.DocumentBuilder;
|
|
|
fa9b16 |
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
fa9b16 |
import javax.xml.transform.OutputKeys;
|
|
|
fa9b16 |
@@ -22,7 +23,6 @@ import org.junit.runner.Description;
|
|
|
fa9b16 |
import org.junit.runner.Result;
|
|
|
fa9b16 |
import org.junit.runner.notification.Failure;
|
|
|
fa9b16 |
import org.junit.runner.notification.RunListener;
|
|
|
fa9b16 |
-
|
|
|
fa9b16 |
import org.w3c.dom.Document;
|
|
|
fa9b16 |
import org.w3c.dom.Element;
|
|
|
fa9b16 |
import org.w3c.dom.Text;
|
|
|
fa9b16 |
@@ -64,9 +64,12 @@ public class TestListener extends RunListener {
|
|
|
fa9b16 |
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
fa9b16 |
|
|
|
fa9b16 |
docBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
|
fa9b16 |
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
|
fa9b16 |
docBuilder = docBuilderFactory.newDocumentBuilder();
|
|
|
fa9b16 |
|
|
|
fa9b16 |
transFactory = TransformerFactory.newInstance();
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
|
|
fa9b16 |
+ tranFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
|
|
fa9b16 |
trans = transFactory.newTransformer();
|
|
|
fa9b16 |
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
|
fa9b16 |
|
|
|
fa9b16 |
--
|
|
|
fa9b16 |
2.35.1
|
|
|
fa9b16 |
|