CVE-2023-4218: Improper Restriction of XML External Entity Reference (CWE-611)
value: In Eclipse IDE versions < 2023-09 (4.29) some files with xml content are parsed vulnerable against all sorts of XXE attacks. The user just needs to open any evil project or update an open project with a vulnerable file (for example for review a foreign repository or patch).

CWE description: The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output.
CVSS v3 base score: 5
Published: 2023-11-09T09:15Z
Repository: https://github.com/eclipse-jdt/eclipse.jdt.ui
Language: Java
Files changed: org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/JUnitModel.java, org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/util/XmlProcessorFactoryJdtJunit.java, org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/jarexport/FatJarExportTests.java, org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/template/java/TemplateSet.java	, org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/History.java	, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageReader.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageWriter.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/FatJarRsrcUrlAntExporter.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackFatJarAntExporter.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackJarAntExporter.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocReader.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocWriter.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/UserLibraryPreferencePage.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileStore.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistHistory.java, org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/util/XmlProcessorFactoryJdtUi.java, org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionReader.java, org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionTransformer.java, org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/XmlProcessorFactoryLtk.java, org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/history/RefactoringHistoryManager.java
Commit date: 2023-07-20 07:42:53 +0200
Commit message: Merge pull request from GHSA-q6xr-9x9x-g7w2

Co-authored-by: Jörg Kubitz <jkubitz-eclipse@gmx.de>
Diff: diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/JUnitModel.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/JUnitModel.java
index 40f88fcd06..c30f6f9c9e 100644
--- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/JUnitModel.java
+++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/model/JUnitModel.java
@@ -31,11 +31,10 @@ import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.sax.SAXSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.InputSource;
@@ -64,10 +63,11 @@ import org.eclipse.jdt.internal.junit.BasicElementLabels;
 import org.eclipse.jdt.internal.junit.JUnitCorePlugin;
 import org.eclipse.jdt.internal.junit.JUnitPreferencesConstants;
 import org.eclipse.jdt.internal.junit.Messages;
 import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
 import org.eclipse.jdt.internal.junit.model.TestElement.Status;
+import org.eclipse.jdt.internal.junit.util.XmlProcessorFactoryJdtJunit;
 
 /**
  * Central registry for JUnit test runs.
  */
 public final class JUnitModel {
@@ -383,11 +383,11 @@ public final class JUnitModel {
 	 * @return the imported test run session
 	 * @throws CoreException if the import failed
 	 */
 	public static TestRunSession importTestRunSession(File file) throws CoreException {
 		try {
-			SAXParserFactory parserFactory= SAXParserFactory.newInstance();
+			SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
 //			parserFactory.setValidating(true); // TODO: add DTD and debug flag
 			SAXParser parser= parserFactory.newSAXParser();
 			TestRunHandler handler= new TestRunHandler();
 			parser.parse(file, handler);
 			TestRunSession session= handler.getTestRunSession();
@@ -424,11 +424,11 @@ public final class JUnitModel {
 
 		Thread importThread= new Thread("JUnit URL importer") { //$NON-NLS-1$
 			@Override
 			public void run() {
 				try {
-					SAXParserFactory parserFactory= SAXParserFactory.newInstance();
+					SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
 //					parserFactory.setValidating(true); // TODO: add DTD and debug flag
 					SAXParser parser= parserFactory.newSAXParser();
 					parser.parse(trimmedUrl, handler);
 					session[0]= handler.getTestRunSession();
 				} catch (OperationCanceledException e) {
@@ -470,11 +470,11 @@ public final class JUnitModel {
 		return session[0];
 	}
 
 	public static void importIntoTestRunSession(File swapFile, TestRunSession testRunSession) throws CoreException {
 		try {
-			SAXParserFactory parserFactory= SAXParserFactory.newInstance();
+			SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
 //			parserFactory.setValidating(true); // TODO: add DTD and debug flag
 			SAXParser parser= parserFactory.newSAXParser();
 			TestRunHandler handler= new TestRunHandler(testRunSession);
 			parser.parse(swapFile, handler);
 		} catch (ParserConfigurationException | SAXException e) {
@@ -505,11 +505,11 @@ public final class JUnitModel {
 	}
 
 	public static void exportTestRunSession(TestRunSession testRunSession, OutputStream out)
 			throws TransformerFactoryConfigurationError, TransformerException {
 
-		Transformer transformer= TransformerFactory.newInstance().newTransformer();
+		Transformer transformer= XmlProcessorFactoryJdtJunit.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 		InputSource inputSource= new InputSource();
 		SAXSource source= new SAXSource(new TestRunSessionSerializer(testRunSession), inputSource);
 		StreamResult result= new StreamResult(out);
 		transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/util/XmlProcessorFactoryJdtJunit.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/util/XmlProcessorFactoryJdtJunit.java
new file mode 100644
index 0000000000..27592366b8
--- /dev/null
+++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/util/XmlProcessorFactoryJdtJunit.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ *  Copyright (c) 2023 Joerg Kubitz and others.
+ *
+ *  This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License 2.0
+ *  which accompanies this distribution, and is available at
+ *  https://www.eclipse.org/legal/epl-2.0/
+ *
+ *  SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jdt.internal.junit.util;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.TransformerFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ * XML processing which prohibits external entities.
+ *
+ * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
+ */
+public class XmlProcessorFactoryJdtJunit {
+	private XmlProcessorFactoryJdtJunit() {
+		// static Utility only
+	}
+
+	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
+	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();
+
+	/**
+	 * Creates TransformerFactory which throws TransformerException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.transform.TransformerFactory
+	 */
+	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
+		TransformerFactory factory = TransformerFactory.newInstance();
+		// prohibit the use of all protocols by external entities:
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities. It's magnitudes faster to call
+	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		// completely disable DOCTYPE declaration:
+		try {
+			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e.getMessage(), e);
+		}
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilder which throws SAXParseException when detecting
+	 * external entities. The builder is not thread safe.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilder
+	 * @throws ParserConfigurationException
+	 */
+	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
+		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		f.setNamespaceAware(awareness);
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// ignore DOCTYPE:
+			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
+			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
+			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
+		return createSAXParserWithErrorOnDOCTYPE(false);
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @param namespaceAware
+	 *            parameter for SAXParserFactory
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
+			throws ParserConfigurationException, SAXException {
+		if (namespaceAware) {
+			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
+		}
+		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
+	}
+
+	/**
+	 * Creates SAXParser which does not throw Exception when detecting external
+	 * entities but ignores them.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserIgnoringDOCTYPE()
+			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
+		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
+		return parser;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/jarexport/FatJarExportTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/jarexport/FatJarExportTests.java
index e1a32b2f81..449c4b10bd 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/jarexport/FatJarExportTests.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/jarexport/FatJarExportTests.java
@@ -32,11 +32,10 @@ import java.io.InputStream;
 import java.util.Map;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
@@ -79,10 +78,11 @@ import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaCore;
 
 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+import org.eclipse.jdt.internal.junit.util.XmlProcessorFactoryJdtJunit;
 
 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
 import org.eclipse.jdt.launching.IVMInstall;
 import org.eclipse.jdt.launching.IVMRunner;
 import org.eclipse.jdt.launching.JavaRuntime;
@@ -671,11 +671,11 @@ public class FatJarExportTests {
 	 * @return root element of the parsed xml-document
 	 * @throws Exception if anything went wrong
 	 */
 	private static Element readXML(IPath xmlFilePath) throws Exception {
 		try (InputStream in = new FileInputStream(xmlFilePath.toFile())) {
-			DocumentBuilder parser= DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			DocumentBuilder parser= XmlProcessorFactoryJdtJunit.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
 			parser.setErrorHandler(new DefaultHandler());
 			Element root= parser.parse(new InputSource(in)).getDocumentElement();
 			in.close();
 
 			return root;
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/template/java/TemplateSet.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/template/java/TemplateSet.java
index e9acfd110d..8dbc354408 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/template/java/TemplateSet.java	
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/template/java/TemplateSet.java	
@@ -26,11 +26,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -50,10 +49,12 @@ import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.text.templates.ContextTypeRegistry;
 import org.eclipse.jface.text.templates.Template;
 import org.eclipse.jface.text.templates.TemplateContextType;
 import org.eclipse.jface.text.templates.TemplateException;
 
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
+
 /**
  * <code>TemplateSet</code> manages a collection of templates and makes them
  * persistent.
  *
  * @deprecated use TemplateStore instead
@@ -106,11 +107,11 @@ public class TemplateSet {
 	 * @param allowDuplicates <code>true</code> if duplicates are allowed
 	 * @throws CoreException if reading fails
 	 */
 	public void addFromStream(InputStream stream, boolean allowDuplicates) throws CoreException {
 		try {
-			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			DocumentBuilder parser= factory.newDocumentBuilder();
 			parser.setErrorHandler(new DefaultHandler());
 			Document document= parser.parse(new InputSource(stream));
 
 			NodeList elements= document.getElementsByTagName(getTemplateTag());
@@ -203,11 +204,11 @@ public class TemplateSet {
 	 * @param stream the stream
 	 * @throws CoreException in case the save operation fails
 	 */
 	public void saveToStream(OutputStream stream) throws CoreException {
 		try {
-			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			DocumentBuilder builder= factory.newDocumentBuilder();
 			Document document= builder.newDocument();
 
 			Node root= document.createElement("templates"); //$NON-NLS-1$
 			document.appendChild(root);
@@ -233,11 +234,11 @@ public class TemplateSet {
 				Text pattern= document.createTextNode(template.getPattern());
 				node.appendChild(pattern);
 			}
 
 
-			Transformer transformer=TransformerFactory.newInstance().newTransformer();
+			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 			DOMSource source = new DOMSource(document);
 			StreamResult result = new StreamResult(stream);
 
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/History.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/History.java
index a13d7a44a3..39006f1bb2 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/History.java	
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/History.java	
@@ -30,11 +30,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.InputSource;
@@ -54,10 +53,11 @@ import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
 import org.eclipse.jdt.internal.corext.CorextMessages;
 
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.JavaUIException;
 import org.eclipse.jdt.internal.ui.JavaUIStatus;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 /**
  * History stores a list of key, object pairs. The list is bounded at size
  * MAX_HISTORY_SIZE. If the list exceeds this size the eldest element is removed
  * from the list. An element can be added/renewed with a call to <code>accessed(Object)</code>.
@@ -230,11 +230,11 @@ public abstract class History<K, V> {
 	}
 
 	private void load(InputSource inputSource) throws CoreException {
 		Element root;
 		try {
-			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
 			parser.setErrorHandler(new DefaultHandler());
 			root = parser.parse(inputSource).getDocumentElement();
 		} catch (SAXException | ParserConfigurationException | IOException e) {
 			throw createException(e, Messages.format(CorextMessages.History_error_read, BasicElementLabels.getResourceName(fFileName)));
 		}
@@ -260,11 +260,11 @@ public abstract class History<K, V> {
 		rebuildPositions();
 	}
 
 	private void save(OutputStream stream) throws CoreException {
 		try {
-			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			DocumentBuilder builder= factory.newDocumentBuilder();
 			Document document= builder.newDocument();
 
 			Element rootElement = document.createElement(fRootNodeName);
 			document.appendChild(rootElement);
@@ -275,11 +275,11 @@ public abstract class History<K, V> {
 				Element element= document.createElement(fInfoNodeName);
 				setAttributes(object, element);
 				rootElement.appendChild(element);
 			}
 
-			Transformer transformer=TransformerFactory.newInstance().newTransformer();
+			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 			DOMSource source = new DOMSource(document);
 			StreamResult result = new StreamResult(stream);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageReader.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageReader.java
index 69efa9c50a..73ed3113ed 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageReader.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageReader.java
@@ -67,10 +67,11 @@ import org.eclipse.jdt.internal.corext.util.Messages;
 import org.eclipse.jdt.ui.jarpackager.IJarDescriptionReader;
 import org.eclipse.jdt.ui.jarpackager.JarPackageData;
 
 import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
 import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 /**
  * Reads data from an InputStream and returns a JarPackage
  */
 public class JarPackageReader extends Object implements IJarDescriptionReader {
@@ -118,11 +119,11 @@ public class JarPackageReader extends Object implements IJarDescriptionReader {
 				throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, message, ex));
 			}
 	}
 
 	public JarPackageData readXML(JarPackageData jarPackage) throws IOException, SAXException {
-	  	DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+	  	DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
     	factory.setValidating(false);
 		DocumentBuilder parser= null;
 
 		try {
 			parser= factory.newDocumentBuilder();
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageWriter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageWriter.java
index 9c3d11750a..c5933bb78b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageWriter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarPackageWriter.java
@@ -25,11 +25,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
@@ -54,10 +53,11 @@ import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.ui.jarpackager.IJarDescriptionWriter;
 import org.eclipse.jdt.ui.jarpackager.JarPackageData;
 
 import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
 import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 /**
  * Writes a JarPackage to an underlying OutputStream
  */
 public class JarPackageWriter extends Object implements IJarDescriptionWriter {
@@ -95,11 +95,11 @@ public class JarPackageWriter extends Object implements IJarDescriptionWriter {
 	 * @exception IOException if writing to the underlying stream fails
 	 */
 	public void writeXML(JarPackageData jarPackage) throws IOException {
 		Assert.isNotNull(jarPackage);
 		DocumentBuilder docBuilder= null;
-		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 		factory.setValidating(false);
 		try {
 	    	docBuilder= factory.newDocumentBuilder();
 		} catch (ParserConfigurationException ex) {
 			throw new IOException(JarPackagerMessages.JarWriter_error_couldNotGetXmlBuilder);
@@ -117,11 +117,11 @@ public class JarPackageWriter extends Object implements IJarDescriptionWriter {
 			xmlWriteManifest(jarPackage, document, xmlJarDesc);
 		xmlWriteSelectedElements(jarPackage, document, xmlJarDesc);
 
 		try {
 			// Write the document to the stream
-			Transformer transformer=TransformerFactory.newInstance().newTransformer();
+			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.ENCODING, fEncoding);
 			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$
 			DOMSource source = new DOMSource(document);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/FatJarRsrcUrlAntExporter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/FatJarRsrcUrlAntExporter.java
index 977aaf8f03..9b079d6858 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/FatJarRsrcUrlAntExporter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/FatJarRsrcUrlAntExporter.java
@@ -29,11 +29,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -42,10 +41,11 @@ import org.w3c.dom.Node;
 import org.eclipse.core.runtime.IPath;
 
 import org.eclipse.debug.core.ILaunchConfiguration;
 
 import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 /**
  * Create an ANT script for a runnable JAR with class loader export. The script is generated based
  * on the classpath of the selected launch-configuration.
  *
@@ -80,11 +80,11 @@ public class FatJarRsrcUrlAntExporter extends FatJarAntExporter {
 	protected void buildANTScript(OutputStream outputStream, String projectName, IPath absJarfile, String mainClass, SourceInfo[] sourceInfos) throws IOException {
 
 		String absJarname= absJarfile.toString();
 
 		DocumentBuilder docBuilder= null;
-		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 		factory.setValidating(false);
 		try {
 			docBuilder= factory.newDocumentBuilder();
 		} catch (ParserConfigurationException ex) {
 			throw new IOException(FatJarPackagerMessages.FatJarPackageAntScript_error_couldNotGetXmlBuilder);
@@ -162,11 +162,11 @@ public class FatJarRsrcUrlAntExporter extends FatJarAntExporter {
 			}
 		}
 
 		try {
 			// Write the document to the stream
-			Transformer transformer= TransformerFactory.newInstance().newTransformer();
+			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
 			DOMSource source= new DOMSource(document);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackFatJarAntExporter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackFatJarAntExporter.java
index af9d84b4b0..b4aaeec1e4 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackFatJarAntExporter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackFatJarAntExporter.java
@@ -25,11 +25,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -37,10 +36,12 @@ import org.w3c.dom.Node;
 
 import org.eclipse.core.runtime.IPath;
 
 import org.eclipse.debug.core.ILaunchConfiguration;
 
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
+
 /**
  * @since 3.5
  */
 public class UnpackFatJarAntExporter extends FatJarAntExporter {
 
@@ -52,11 +53,11 @@ public class UnpackFatJarAntExporter extends FatJarAntExporter {
 	protected void buildANTScript(IPath antScriptLocation, String projectName, IPath absJarfile, String mainClass, SourceInfo[] sourceInfos) throws IOException {
 		try (OutputStream outputStream = new FileOutputStream(antScriptLocation.toFile())) {
 			String absJarname= absJarfile.toString();
 
 			DocumentBuilder docBuilder= null;
-			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			factory.setValidating(false);
 			try {
 				docBuilder= factory.newDocumentBuilder();
 			} catch (ParserConfigurationException ex) {
 				throw new IOException(FatJarPackagerMessages.FatJarPackageAntScript_error_couldNotGetXmlBuilder);
@@ -112,11 +113,11 @@ public class UnpackFatJarAntExporter extends FatJarAntExporter {
 				}
 			}
 
 			try {
 				// Write the document to the stream
-				Transformer transformer= TransformerFactory.newInstance().newTransformer();
+				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 				transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
 				DOMSource source= new DOMSource(document);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackJarAntExporter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackJarAntExporter.java
index a8fa23ebb2..08ca8d0738 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackJarAntExporter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackagerfat/UnpackJarAntExporter.java
@@ -26,11 +26,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -38,10 +37,12 @@ import org.w3c.dom.Node;
 
 import org.eclipse.core.runtime.IPath;
 
 import org.eclipse.debug.core.ILaunchConfiguration;
 
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
+
 /**
  * Create an ANT script for a runnable JAR wit libraries in a sub-folder. The script is generated
  * based on the classpath of the selected launch-configuration.
  *
  * @since 3.5
@@ -58,11 +59,11 @@ public class UnpackJarAntExporter extends FatJarAntExporter {
 			String absJarname= absJarfile.toString();
 			String subfolder= absJarfile.removeFileExtension().lastSegment() + "_lib"; //$NON-NLS-1$
 			String absSubfolder= absJarfile.removeLastSegments(1).append(subfolder).toString();
 
 			DocumentBuilder docBuilder= null;
-			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			factory.setValidating(false);
 			try {
 				docBuilder= factory.newDocumentBuilder();
 			} catch (ParserConfigurationException ex) {
 				throw new IOException(FatJarPackagerMessages.FatJarPackageAntScript_error_couldNotGetXmlBuilder);
@@ -145,11 +146,11 @@ public class UnpackJarAntExporter extends FatJarAntExporter {
 			}
 
 
 			try {
 				// Write the document to the stream
-				Transformer transformer= TransformerFactory.newInstance().newTransformer();
+				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 				transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
 				DOMSource source= new DOMSource(document);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocReader.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocReader.java
index 0d75b2281f..ad1f48a2a2 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocReader.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocReader.java
@@ -29,10 +29,12 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 import org.eclipse.core.runtime.Assert;
 
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
+
 
 /**
  * Reads data from an InputStream and returns a JarPackage
  */
 public class JavadocReader extends Object {
@@ -60,11 +62,11 @@ public class JavadocReader extends Object {
 			fInputStream.close();
 	}
 
 	public Element readXML() throws IOException, SAXException {
 
-		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 		factory.setValidating(false);
 		DocumentBuilder parser= null;
 		try {
 			parser= factory.newDocumentBuilder();
 		} catch (ParserConfigurationException ex) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocWriter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocWriter.java
index 41f9d3182f..c4f66bcf28 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocWriter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javadocexport/JavadocWriter.java
@@ -24,11 +24,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
@@ -43,10 +42,12 @@ import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IPackageFragment;
 
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
+
 public class JavadocWriter {
 
 	private static final char PATH_SEPARATOR= '/'; // use forward slash for all platforms
 
 	private final IJavaProject[] fJavaProjects;
@@ -62,11 +63,11 @@ public class JavadocWriter {
 		fBasePath= basePath;
 		fJavaProjects= projects;
 	}
 
 	public Element createXML(JavadocOptionsManager store) throws ParserConfigurationException {
-		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 		factory.setValidating(false);
 		DocumentBuilder docBuilder= factory.newDocumentBuilder();
 		Document document= docBuilder.newDocument();
 
 		// Create the document
@@ -99,11 +100,11 @@ public class JavadocWriter {
 	 * @throws TransformerException thrown if writing fails
 	 */
 	public static void writeDocument(Element javadocElement, String encoding, OutputStream outputStream) throws TransformerException {
 
 		// Write the document to the stream
-		Transformer transformer=TransformerFactory.newInstance().newTransformer();
+		Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 		transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 		transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
 		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$
 		DOMSource source = new DOMSource(javadocElement.getOwnerDocument());
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/UserLibraryPreferencePage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/UserLibraryPreferencePage.java
index a3a002c777..2c03c511e7 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/UserLibraryPreferencePage.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/UserLibraryPreferencePage.java
@@ -33,11 +33,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -114,10 +113,11 @@ import org.eclipse.jdt.ui.wizards.ClasspathAttributeConfiguration;
 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
 import org.eclipse.jdt.internal.ui.IUIConstants;
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 import org.eclipse.jdt.internal.ui.wizards.buildpaths.AccessRulesDialog;
 import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter;
 import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementAttribute;
@@ -557,11 +557,11 @@ public class UserLibraryPreferencePage extends PreferencePage implements IWorkbe
 		}
 
 		protected static void saveLibraries(List<CPUserLibraryElement> libraries, File file, String encoding, IProgressMonitor monitor) throws IOException {
 			OutputStream stream= new FileOutputStream(file);
 			try {
-				DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+				DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 				factory.setValidating(false);
 				DocumentBuilder docBuilder= factory.newDocumentBuilder();
 				Document document= docBuilder.newDocument();
 
 				// Create the document
@@ -611,11 +611,11 @@ public class UserLibraryPreferencePage extends PreferencePage implements IWorkbe
 						}
 					}
 				}
 
 				// Write the document to the stream
-				Transformer transformer=TransformerFactory.newInstance().newTransformer();
+				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
 				transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 				transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$
 
@@ -638,11 +638,11 @@ public class UserLibraryPreferencePage extends PreferencePage implements IWorkbe
 
 		private static List<CPUserLibraryElement> loadLibraries(File file) throws IOException {
 			InputStream stream= new FileInputStream(file);
 			Element cpElement;
 			try {
-				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+				DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
 				parser.setErrorHandler(new DefaultHandler());
 				cpElement = parser.parse(new InputSource(stream)).getDocumentElement();
 			} catch (SAXException | ParserConfigurationException e) {
 				throw new IOException(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_badformat);
 			} finally {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileStore.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileStore.java
index 5a151d1052..c42d4ce44b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileStore.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileStore.java
@@ -36,11 +36,10 @@ import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -60,10 +59,11 @@ import org.eclipse.jdt.ui.JavaUI;
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.JavaUIException;
 import org.eclipse.jdt.internal.ui.JavaUIStatus;
 import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.CustomProfile;
 import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.Profile;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 
 /**
  * Can load/store profiles from/to profilesKey
  */
@@ -236,11 +236,11 @@ public class ProfileStore {
 	 */
 	public static List<Profile> readProfilesFromStream(InputSource inputSource) throws CoreException {
 
 		final ProfileDefaultHandler handler= new ProfileDefaultHandler();
 		try {
-		    final SAXParserFactory factory= SAXParserFactory.newInstance();
+		    final SAXParserFactory factory= XmlProcessorFactoryJdtUi.createSAXFactoryWithErrorOnDOCTYPE();
 			final SAXParser parser= factory.newSAXParser();
 			parser.parse(inputSource, handler);
 		} catch (SAXException | IOException | ParserConfigurationException e) {
 			throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
 		}
@@ -276,11 +276,11 @@ public class ProfileStore {
 	 * @throws CoreException
 	 */
 	public static void writeProfilesToStream(Collection<Profile> profiles, OutputStream stream, String encoding, IProfileVersioner profileVersioner) throws CoreException {
 
 		try {
-			final DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+			final DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 			final DocumentBuilder builder= factory.newDocumentBuilder();
 			final Document document= builder.newDocument();
 
 			final Element rootElement = document.createElement(XML_NODE_ROOT);
 			rootElement.setAttribute(XML_ATTRIBUTE_VERSION, Integer.toString(profileVersioner.getCurrentVersion()));
@@ -292,11 +292,11 @@ public class ProfileStore {
 					final Element profileElement= createProfileElement(profile, document, profileVersioner);
 					rootElement.appendChild(profileElement);
 				}
 			}
 
-			Transformer transformer=TransformerFactory.newInstance().newTransformer();
+			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 			transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
 			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
 			transformer.transform(new DOMSource(document), new StreamResult(stream));
 		} catch (TransformerException | ParserConfigurationException e) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistHistory.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistHistory.java
index 3a18c3cd1c..be49cd74d6 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistHistory.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistHistory.java
@@ -32,11 +32,10 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -60,10 +59,11 @@ import org.eclipse.jdt.core.ITypeHierarchy;
 import org.eclipse.jdt.core.JavaModelException;
 
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.JavaUIException;
 import org.eclipse.jdt.internal.ui.JavaUIStatus;
+import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
 
 /**
  * An LRU cache for code assist.
  *
  * @since 3.2
@@ -83,11 +83,11 @@ public final class ContentAssistHistory {
 		private static final String ATTRIBUTE_MAX_LHS= "maxLHS"; //$NON-NLS-1$
 		private static final String ATTRIBUTE_MAX_RHS= "maxRHS"; //$NON-NLS-1$
 
 		public void store(ContentAssistHistory history, StreamResult result) throws CoreException {
 			try {
-				DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+				DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
 				DocumentBuilder builder= factory.newDocumentBuilder();
 				Document document= builder.newDocument();
 
 				Element rootElement = document.createElement(NODE_ROOT);
 				rootElement.setAttribute(ATTRIBUTE_MAX_LHS, Integer.toString(history.fMaxLHS));
@@ -104,11 +104,11 @@ public final class ContentAssistHistory {
 						rhsElement.setAttribute(ATTRIBUTE_NAME, rhs);
 						lhsElement.appendChild(rhsElement);
 					}
 				}
 
-				Transformer transformer=TransformerFactory.newInstance().newTransformer();
+				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
 				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
 				transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$
 				DOMSource source = new DOMSource(document);
 
@@ -119,11 +119,11 @@ public final class ContentAssistHistory {
 		}
 
 		public ContentAssistHistory load(InputSource source) throws CoreException {
 			Element root;
 			try {
-				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+				DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
 				parser.setErrorHandler(new DefaultHandler());
 				root = parser.parse(source).getDocumentElement();
 			} catch (SAXException | ParserConfigurationException | IOException e) {
 				throw createException(e, JavaTextMessages.ContentAssistHistory_deserialize_error);
 			}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/util/XmlProcessorFactoryJdtUi.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/util/XmlProcessorFactoryJdtUi.java
new file mode 100644
index 0000000000..16b16594ad
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/util/XmlProcessorFactoryJdtUi.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ *  Copyright (c) 2023 Joerg Kubitz and others.
+ *
+ *  This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License 2.0
+ *  which accompanies this distribution, and is available at
+ *  https://www.eclipse.org/legal/epl-2.0/
+ *
+ *  SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.util;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.TransformerFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ * XML processing which prohibits external entities.
+ *
+ * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
+ */
+public class XmlProcessorFactoryJdtUi {
+	private XmlProcessorFactoryJdtUi() {
+		// static Utility only
+	}
+
+	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
+	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();
+
+	/**
+	 * Creates TransformerFactory which throws TransformerException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.transform.TransformerFactory
+	 */
+	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
+		TransformerFactory factory = TransformerFactory.newInstance();
+		// prohibit the use of all protocols by external entities:
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities. It's magnitudes faster to call
+	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		// completely disable DOCTYPE declaration:
+		try {
+			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e.getMessage(), e);
+		}
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilder which throws SAXParseException when detecting
+	 * external entities. The builder is not thread safe.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilder
+	 * @throws ParserConfigurationException
+	 */
+	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
+		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		f.setNamespaceAware(awareness);
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// ignore DOCTYPE:
+			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
+			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
+			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
+		return createSAXParserWithErrorOnDOCTYPE(false);
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @param namespaceAware
+	 *            parameter for SAXParserFactory
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
+			throws ParserConfigurationException, SAXException {
+		if (namespaceAware) {
+			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
+		}
+		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
+	}
+
+	/**
+	 * Creates SAXParser which does not throw Exception when detecting external
+	 * entities but ignores them.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserIgnoringDOCTYPE()
+			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
+		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
+		return parser;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionReader.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionReader.java
index 0d584c8d3d..34529b04f7 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionReader.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionReader.java
@@ -134,11 +134,11 @@ public final class RefactoringSessionReader extends DefaultHandler {
 	 */
 	public RefactoringSessionDescriptor readSession(final InputSource source) throws CoreException {
 		fSessionFound= false;
 		try {
 			source.setSystemId("/"); //$NON-NLS-1$
-			createParser(SAXParserFactory.newInstance()).parse(source, this);
+			createParser(XmlProcessorFactoryLtk.createSAXFactoryWithErrorOnDOCTYPE()).parse(source, this);
 			if (!fSessionFound)
 				throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR, RefactoringCoreMessages.RefactoringSessionReader_no_session, null));
 			if (fRefactoringDescriptors != null) {
 				if (fVersion == null || "".equals(fVersion)) //$NON-NLS-1$
 					throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.MISSING_REFACTORING_HISTORY_VERSION, RefactoringCoreMessages.RefactoringSessionReader_missing_version_information, null));
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionTransformer.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionTransformer.java
index 06c250e11e..c401fe283b 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionTransformer.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/RefactoringSessionTransformer.java
@@ -17,11 +17,10 @@ import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
@@ -133,11 +132,11 @@ public final class RefactoringSessionTransformer {
 		Assert.isNotNull(id);
 		Assert.isNotNull(description);
 		Assert.isTrue(flags >= RefactoringDescriptor.NONE);
 		try {
 			if (fDocument == null)
-				fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+				fDocument= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder().newDocument();
 		} catch (ParserConfigurationException | FactoryConfigurationError exception) {
 			throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_IO_ERROR, exception.getLocalizedMessage(), null));
 		}
 		if (fRefactoring == null) {
 			try {
@@ -198,11 +197,11 @@ public final class RefactoringSessionTransformer {
 	 *             if an error occurs while creating a new session
 	 */
 	public void beginSession(final String comment, final String version) throws CoreException {
 		if (fDocument == null) {
 			try {
-				fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+				fDocument= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder().newDocument();
 				fSession= fDocument.createElement(IRefactoringSerializationConstants.ELEMENT_SESSION);
 				fSessionArguments= new ArrayList<>(2);
 				Attr attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_VERSION);
 				attribute.setValue(version);
 				fSessionArguments.add(attribute);
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/XmlProcessorFactoryLtk.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/XmlProcessorFactoryLtk.java
new file mode 100644
index 0000000000..281119fb52
--- /dev/null
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/XmlProcessorFactoryLtk.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ *  Copyright (c) 2023 Joerg Kubitz and others.
+ *
+ *  This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License 2.0
+ *  which accompanies this distribution, and is available at
+ *  https://www.eclipse.org/legal/epl-2.0/
+ *
+ *  SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.ltk.internal.core.refactoring;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.TransformerFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ * XML processing which prohibits external entities.
+ *
+ * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
+ */
+public class XmlProcessorFactoryLtk {
+	private XmlProcessorFactoryLtk() {
+		// static Utility only
+	}
+
+	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
+	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
+	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();
+
+	/**
+	 * Creates TransformerFactory which throws TransformerException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.transform.TransformerFactory
+	 */
+	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
+		TransformerFactory factory = TransformerFactory.newInstance();
+		// prohibit the use of all protocols by external entities:
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities. It's magnitudes faster to call
+	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		// completely disable DOCTYPE declaration:
+		try {
+			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e.getMessage(), e);
+		}
+		return factory;
+	}
+
+	/**
+	 * Creates DocumentBuilder which throws SAXParseException when detecting
+	 * external entities. The builder is not thread safe.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilder
+	 * @throws ParserConfigurationException
+	 */
+	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
+		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
+	}
+
+	/**
+	 * Creates DocumentBuilderFactory which throws SAXParseException when
+	 * detecting external entities.
+	 *
+	 * @return javax.xml.parsers.DocumentBuilderFactory
+	 */
+	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		f.setNamespaceAware(awareness);
+		try {
+			// force org.xml.sax.SAXParseException for any DOCTYPE:
+			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
+		SAXParserFactory f = SAXParserFactory.newInstance();
+		try {
+			// ignore DOCTYPE:
+			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
+			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
+			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return f;
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
+		return createSAXParserWithErrorOnDOCTYPE(false);
+	}
+
+	/**
+	 * Creates SAXParser which throws SAXParseException when detecting external
+	 * entities.
+	 *
+	 * @param namespaceAware
+	 *            parameter for SAXParserFactory
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
+			throws ParserConfigurationException, SAXException {
+		if (namespaceAware) {
+			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
+		}
+		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
+	}
+
+	/**
+	 * Creates SAXParser which does not throw Exception when detecting external
+	 * entities but ignores them.
+	 *
+	 * @return javax.xml.parsers.SAXParser
+	 */
+	public static SAXParser createSAXParserIgnoringDOCTYPE()
+			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
+		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
+		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
+		return parser;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/history/RefactoringHistoryManager.java b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/history/RefactoringHistoryManager.java
index 5bf3f09b27..7bf6786743 100644
--- a/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/history/RefactoringHistoryManager.java
+++ b/org.eclipse.ltk.core.refactoring/src/org/eclipse/ltk/internal/core/refactoring/history/RefactoringHistoryManager.java
@@ -37,11 +37,10 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TimeZone;
 
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -82,10 +81,11 @@ import org.eclipse.ltk.internal.core.refactoring.IRefactoringSerializationConsta
 import org.eclipse.ltk.internal.core.refactoring.Messages;
 import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
 import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin;
 import org.eclipse.ltk.internal.core.refactoring.RefactoringSessionReader;
 import org.eclipse.ltk.internal.core.refactoring.RefactoringSessionTransformer;
+import org.eclipse.ltk.internal.core.refactoring.XmlProcessorFactoryLtk;
 
 /**
  * Manager for persistable refactoring histories.
  *
  * @since 3.2
@@ -863,11 +863,11 @@ public final class RefactoringHistoryManager {
 	 *             if an error occurs in the parser configuration
 	 */
 	private Document getCachedDocument(final IPath path, final InputStream input) throws SAXException, IOException, ParserConfigurationException {
 		if (path.equals(fCachedPath) && fCachedDocument != null)
 			return fCachedDocument;
-		DocumentBuilder parser= DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		DocumentBuilder parser= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
 		parser.setErrorHandler(new DefaultHandler());
 		final Document document= parser.parse(new InputSource(input));
 		fCachedDocument= document;
 		fCachedPath= path;
 		return document;

Vulnerable code: import javax.xml.transform.TransformerFactory;
			SAXParserFactory parserFactory= SAXParserFactory.newInstance();
					SAXParserFactory parserFactory= SAXParserFactory.newInstance();
			SAXParserFactory parserFactory= SAXParserFactory.newInstance();
		Transformer transformer= TransformerFactory.newInstance().newTransformer();
import javax.xml.parsers.DocumentBuilderFactory;
			DocumentBuilder parser= DocumentBuilderFactory.newInstance().newDocumentBuilder();
import javax.xml.transform.TransformerFactory;
			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			Transformer transformer=TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			Transformer transformer=TransformerFactory.newInstance().newTransformer();
	  	DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
import javax.xml.transform.TransformerFactory;
		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			Transformer transformer=TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			Transformer transformer= TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
				Transformer transformer= TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
			DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
				Transformer transformer= TransformerFactory.newInstance().newTransformer();
		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
import javax.xml.transform.TransformerFactory;
		DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
		Transformer transformer=TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
				DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
				Transformer transformer=TransformerFactory.newInstance().newTransformer();
				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
import javax.xml.transform.TransformerFactory;
		    final SAXParserFactory factory= SAXParserFactory.newInstance();
			final DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
			Transformer transformer=TransformerFactory.newInstance().newTransformer();
import javax.xml.transform.TransformerFactory;
				DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
				Transformer transformer=TransformerFactory.newInstance().newTransformer();
				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			createParser(SAXParserFactory.newInstance()).parse(source, this);
import javax.xml.parsers.DocumentBuilderFactory;
				fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
				fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
import javax.xml.parsers.DocumentBuilderFactory;
		DocumentBuilder parser= DocumentBuilderFactory.newInstance().newDocumentBuilder();
Fixed code: import org.eclipse.jdt.internal.junit.util.XmlProcessorFactoryJdtJunit;
			SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
					SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
			SAXParserFactory parserFactory= XmlProcessorFactoryJdtJunit.createSAXFactoryWithErrorOnDOCTYPE();
		Transformer transformer= XmlProcessorFactoryJdtJunit.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
/*******************************************************************************
 *  Copyright (c) 2023 Joerg Kubitz and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.jdt.internal.junit.util;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;

import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

/**
 * XML processing which prohibits external entities.
 *
 * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
 */
public class XmlProcessorFactoryJdtJunit {
	private XmlProcessorFactoryJdtJunit() {
		// static Utility only
	}

	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();

	/**
	 * Creates TransformerFactory which throws TransformerException when
	 * detecting external entities.
	 *
	 * @return javax.xml.transform.TransformerFactory
	 */
	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
		TransformerFactory factory = TransformerFactory.newInstance();
		// prohibit the use of all protocols by external entities:
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
		return factory;
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities. It's magnitudes faster to call
	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// completely disable DOCTYPE declaration:
		try {
			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		return factory;
	}

	/**
	 * Creates DocumentBuilder which throws SAXParseException when detecting
	 * external entities. The builder is not thread safe.
	 *
	 * @return javax.xml.parsers.DocumentBuilder
	 * @throws ParserConfigurationException
	 */
	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
		SAXParserFactory f = SAXParserFactory.newInstance();
		f.setNamespaceAware(awareness);
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// ignore DOCTYPE:
			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */

	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
		return createSAXParserWithErrorOnDOCTYPE(false);
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @param namespaceAware
	 *            parameter for SAXParserFactory
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
			throws ParserConfigurationException, SAXException {
		if (namespaceAware) {
			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
		}
		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
	}

	/**
	 * Creates SAXParser which does not throw Exception when detecting external
	 * entities but ignores them.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserIgnoringDOCTYPE()
			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
		return parser;
	}
}
import org.eclipse.jdt.internal.junit.util.XmlProcessorFactoryJdtJunit;
			DocumentBuilder parser= XmlProcessorFactoryJdtJunit.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;

			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
			DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
	  	DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;

			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;

			DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;

		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;

		DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
		Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
				DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
				DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
		    final SAXParserFactory factory= XmlProcessorFactoryJdtUi.createSAXFactoryWithErrorOnDOCTYPE();
			final DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
			Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
import org.eclipse.jdt.internal.ui.util.XmlProcessorFactoryJdtUi;
				DocumentBuilderFactory factory= XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE();
				Transformer transformer= XmlProcessorFactoryJdtUi.createTransformerFactoryWithErrorOnDOCTYPE().newTransformer();
				DocumentBuilder parser = XmlProcessorFactoryJdtUi.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();
/*******************************************************************************
 *  Copyright (c) 2023 Joerg Kubitz and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.util;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;

import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

/**
 * XML processing which prohibits external entities.
 *
 * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
 */
public class XmlProcessorFactoryJdtUi {
	private XmlProcessorFactoryJdtUi() {
		// static Utility only
	}

	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();

	/**
	 * Creates TransformerFactory which throws TransformerException when
	 * detecting external entities.
	 *
	 * @return javax.xml.transform.TransformerFactory
	 */
	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
		TransformerFactory factory = TransformerFactory.newInstance();
		// prohibit the use of all protocols by external entities:
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
		return factory;
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities. It's magnitudes faster to call
	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// completely disable DOCTYPE declaration:
		try {
			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		return factory;
	}

	/**
	 * Creates DocumentBuilder which throws SAXParseException when detecting
	 * external entities. The builder is not thread safe.
	 *
	 * @return javax.xml.parsers.DocumentBuilder
	 * @throws ParserConfigurationException
	 */
	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
		SAXParserFactory f = SAXParserFactory.newInstance();
		f.setNamespaceAware(awareness);
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// ignore DOCTYPE:
			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */

	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
		return createSAXParserWithErrorOnDOCTYPE(false);
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @param namespaceAware
	 *            parameter for SAXParserFactory
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
			throws ParserConfigurationException, SAXException {
		if (namespaceAware) {
			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
		}
		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
	}

	/**
	 * Creates SAXParser which does not throw Exception when detecting external
	 * entities but ignores them.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserIgnoringDOCTYPE()
			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
		return parser;
	}
}
			createParser(XmlProcessorFactoryLtk.createSAXFactoryWithErrorOnDOCTYPE()).parse(source, this);
				fDocument= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder().newDocument();
				fDocument= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder().newDocument();
/*******************************************************************************
 *  Copyright (c) 2023 Joerg Kubitz and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.ltk.internal.core.refactoring;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;

import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

/**
 * XML processing which prohibits external entities.
 *
 * @see <a href="https://rules.sonarsource.com/java/RSPEC-2755/">RSPEC-2755</a>
 */
public class XmlProcessorFactoryLtk {
	private XmlProcessorFactoryLtk() {
		// static Utility only
	}

	private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE = createDocumentBuilderFactoryWithErrorOnDOCTYPE();
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE = createSAXFactoryWithErrorOnDOCTYPE(false);
	private static final SAXParserFactory SAX_FACTORY_ERROR_ON_DOCTYPE_NS = createSAXFactoryWithErrorOnDOCTYPE(true);
	private static final SAXParserFactory SAX_FACTORY_IGNORING_DOCTYPE = createSAXFactoryIgnoringDOCTYPE();

	/**
	 * Creates TransformerFactory which throws TransformerException when
	 * detecting external entities.
	 *
	 * @return javax.xml.transform.TransformerFactory
	 */
	public static TransformerFactory createTransformerFactoryWithErrorOnDOCTYPE() {
		TransformerFactory factory = TransformerFactory.newInstance();
		// prohibit the use of all protocols by external entities:
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); //$NON-NLS-1$
		return factory;
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities. It's magnitudes faster to call
	 * {@link #createDocumentBuilderWithErrorOnDOCTYPE()}.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static synchronized DocumentBuilderFactory createDocumentBuilderFactoryWithErrorOnDOCTYPE() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// completely disable DOCTYPE declaration:
		try {
			factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		return factory;
	}

	/**
	 * Creates DocumentBuilder which throws SAXParseException when detecting
	 * external entities. The builder is not thread safe.
	 *
	 * @return javax.xml.parsers.DocumentBuilder
	 * @throws ParserConfigurationException
	 */
	public static DocumentBuilder createDocumentBuilderWithErrorOnDOCTYPE() throws ParserConfigurationException {
		return DOCUMENT_BUILDER_FACTORY_ERROR_ON_DOCTYPE.newDocumentBuilder();
	}

	/**
	 * Creates DocumentBuilderFactory which throws SAXParseException when
	 * detecting external entities.
	 *
	 * @return javax.xml.parsers.DocumentBuilderFactory
	 */
	public static SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryWithErrorOnDOCTYPE(boolean awareness) {
		SAXParserFactory f = SAXParserFactory.newInstance();
		f.setNamespaceAware(awareness);
		try {
			// force org.xml.sax.SAXParseException for any DOCTYPE:
			f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	private static synchronized SAXParserFactory createSAXFactoryIgnoringDOCTYPE() {
		SAXParserFactory f = SAXParserFactory.newInstance();
		try {
			// ignore DOCTYPE:
			f.setFeature("http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
			f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
			f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return f;
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */

	public static SAXParser createSAXParserWithErrorOnDOCTYPE() throws ParserConfigurationException, SAXException {
		return createSAXParserWithErrorOnDOCTYPE(false);
	}

	/**
	 * Creates SAXParser which throws SAXParseException when detecting external
	 * entities.
	 *
	 * @param namespaceAware
	 *            parameter for SAXParserFactory
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserWithErrorOnDOCTYPE(boolean namespaceAware)
			throws ParserConfigurationException, SAXException {
		if (namespaceAware) {
			return SAX_FACTORY_ERROR_ON_DOCTYPE_NS.newSAXParser();
		}
		return SAX_FACTORY_ERROR_ON_DOCTYPE.newSAXParser();
	}

	/**
	 * Creates SAXParser which does not throw Exception when detecting external
	 * entities but ignores them.
	 *
	 * @return javax.xml.parsers.SAXParser
	 */
	public static SAXParser createSAXParserIgnoringDOCTYPE()
			throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException {
		SAXParser parser = SAX_FACTORY_IGNORING_DOCTYPE.newSAXParser();
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); //$NON-NLS-1$
		parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); //$NON-NLS-1$
		return parser;
	}
}
import org.eclipse.ltk.internal.core.refactoring.XmlProcessorFactoryLtk;
		DocumentBuilder parser= XmlProcessorFactoryLtk.createDocumentBuilderFactoryWithErrorOnDOCTYPE().newDocumentBuilder();