Index: mysql-connector-java-5.1.47/src/com/mysql/jdbc/JDBC4MysqlSQLXML.java
===================================================================
--- mysql-connector-java-5.1.47.orig/src/com/mysql/jdbc/JDBC4MysqlSQLXML.java
+++ mysql-connector-java-5.1.47/src/com/mysql/jdbc/JDBC4MysqlSQLXML.java
@@ -39,6 +39,7 @@ import java.sql.SQLXML;
 
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerFactory;
+import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.FactoryConfigurationError;
@@ -66,6 +67,11 @@ import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.helpers.DefaultHandler;
 import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import com.mysql.jdbc.MysqlErrorNumbers;
+
 
 public class JDBC4MysqlSQLXML implements SQLXML {
 
@@ -280,31 +286,41 @@ public class JDBC4MysqlSQLXML implements
         // (futureproofing)
 
         if (clazz == null || clazz.equals(SAXSource.class)) {
-
-            InputSource inputSource = null;
-
-            if (this.fromResultSet) {
-                inputSource = new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml));
-            } else {
-                inputSource = new InputSource(new StringReader(this.stringRep));
-            }
-
-            return (T) new SAXSource(inputSource);
+            try {
+                XMLReader reader = XMLReaderFactory.createXMLReader();
+                // According to https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+                setFeature(reader, "http://apache.org/xml/features/disallow-doctype-decl", true);
+                setFeature(reader, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+                setFeature(reader, "http://xml.org/sax/features/external-general-entities", false);
+                setFeature(reader, "http://xml.org/sax/features/external-parameter-entities", false);
+
+                return (T) new SAXSource(reader, this.fromResultSet ? new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml))
+                        : new InputSource(new StringReader(this.stringRep)));
+            } catch (SAXException ex) {
+                SQLException sqlEx = SQLError.createSQLException(ex.getMessage(), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, ex, this.exceptionInterceptor);
+                throw sqlEx;  
+            }          
         } else if (clazz.equals(DOMSource.class)) {
             try {
                 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                 builderFactory.setNamespaceAware(true);
-                DocumentBuilder builder = builderFactory.newDocumentBuilder();
-
-                InputSource inputSource = null;
+                
+                // According to https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+                setFeature(builderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
+                setFeature(builderFactory, "http://apache.org/xml/features/disallow-doctype-decl", true);
+                setFeature(builderFactory, "http://xml.org/sax/features/external-general-entities", false);
+                setFeature(builderFactory, "http://xml.org/sax/features/external-parameter-entities", false);
+                setFeature(builderFactory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+                builderFactory.setXIncludeAware(false);
+                builderFactory.setExpandEntityReferences(false);
 
-                if (this.fromResultSet) {
-                    inputSource = new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml));
-                } else {
-                    inputSource = new InputSource(new StringReader(this.stringRep));
-                }
+                builderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
 
-                return (T) new DOMSource(builder.parse(inputSource));
+                DocumentBuilder builder = builderFactory.newDocumentBuilder();
+ 
+                return (T) new DOMSource(builder.parse(this.fromResultSet ? new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml))
+                        : new InputSource(new StringReader(this.stringRep))));
             } catch (Throwable t) {
                 SQLException sqlEx = SQLError.createSQLException(t.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
                 sqlEx.initCause(t);
@@ -313,26 +329,11 @@ public class JDBC4MysqlSQLXML implements
             }
 
         } else if (clazz.equals(StreamSource.class)) {
-            Reader reader = null;
-
-            if (this.fromResultSet) {
-                reader = this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
-            } else {
-                reader = new StringReader(this.stringRep);
-            }
-
-            return (T) new StreamSource(reader);
+            return (T) new StreamSource(this.fromResultSet ? this.owningResultSet.getCharacterStream(this.columnIndexOfXml) : new StringReader(this.stringRep));
         } else if (clazz.equals(StAXSource.class)) {
             try {
-                Reader reader = null;
-
-                if (this.fromResultSet) {
-                    reader = this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
-                } else {
-                    reader = new StringReader(this.stringRep);
-                }
-
-                return (T) new StAXSource(this.inputFactory.createXMLStreamReader(reader));
+                return (T) new StAXSource(this.inputFactory.createXMLStreamReader(
+                        this.fromResultSet ? this.owningResultSet.getCharacterStream(this.columnIndexOfXml) : new StringReader(this.stringRep)));
             } catch (XMLStreamException ex) {
                 SQLException sqlEx = SQLError.createSQLException(ex.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
                 sqlEx.initCause(ex);
@@ -345,6 +346,18 @@ public class JDBC4MysqlSQLXML implements
         }
     }
 
+    private static void setFeature(Object factory, String name, boolean value) {
+        try {
+            if (factory instanceof DocumentBuilderFactory) {
+                ((DocumentBuilderFactory) factory).setFeature(name, value);
+            } else if (factory instanceof XMLReader) {
+                ((XMLReader) factory).setFeature(name, value);
+            }
+        } catch (Exception ignore) {
+            // no-op
+        }
+    }
+
     /**
      * Retrieves a stream that can be used to write the XML value that this
      * SQLXML instance represents. The stream begins at position 0. The bytes of
@@ -562,7 +575,7 @@ public class JDBC4MysqlSQLXML implements
 
     protected synchronized Reader serializeAsCharacterStream() throws SQLException {
         checkClosed();
-        if (this.workingWithResult) {
+        if (this.workingWithResult || this.owningResultSet == null) {
             // figure out what kind of result
             if (this.stringRep != null) {
                 return new StringReader(this.stringRep);
Index: mysql-connector-java-5.1.47/src/com/mysql/jdbc/MysqlErrorNumbers.java
===================================================================
--- mysql-connector-java-5.1.47.orig/src/com/mysql/jdbc/MysqlErrorNumbers.java
+++ mysql-connector-java-5.1.47/src/com/mysql/jdbc/MysqlErrorNumbers.java
@@ -947,6 +947,8 @@ public final class MysqlErrorNumbers {
     public static final int ERROR_CODE_NULL_LOAD_BALANCED_CONNECTION = 1000001;
     public static final int ERROR_CODE_REPLICATION_CONNECTION_WITH_NO_HOSTS = 1000002;
 
+    public static final String SQL_STATE_ILLEGAL_ARGUMENT = "S1009";
+
     private MysqlErrorNumbers() {
         // prevent instantiation
     }
