1
1
/*
2
- * Copyright (c) 2002, 2020 , Oracle and/or its affiliates.
2
+ * Copyright (c) 2002, 2021 , Oracle and/or its affiliates.
3
3
*
4
4
* This program is free software; you can redistribute it and/or modify it under
5
5
* the terms of the GNU General Public License, version 2.0, as published by the
42
42
import java .sql .SQLException ;
43
43
import java .sql .SQLXML ;
44
44
45
+ import javax .xml .XMLConstants ;
45
46
import javax .xml .parsers .DocumentBuilder ;
46
47
import javax .xml .parsers .DocumentBuilderFactory ;
47
48
import javax .xml .stream .XMLInputFactory ;
65
66
import org .xml .sax .Attributes ;
66
67
import org .xml .sax .InputSource ;
67
68
import org .xml .sax .SAXException ;
69
+ import org .xml .sax .XMLReader ;
68
70
import org .xml .sax .helpers .DefaultHandler ;
71
+ import org .xml .sax .helpers .XMLReaderFactory ;
69
72
70
73
import com .mysql .cj .Messages ;
71
74
import com .mysql .cj .exceptions .ExceptionInterceptor ;
@@ -199,56 +202,54 @@ public <T extends Source> T getSource(Class<T> clazz) throws SQLException {
199
202
200
203
if (clazz == null || clazz .equals (SAXSource .class )) {
201
204
202
- InputSource inputSource = null ;
203
-
204
- if (this .fromResultSet ) {
205
- inputSource = new InputSource (this .owningResultSet .getCharacterStream (this .columnIndexOfXml ));
206
- } else {
207
- inputSource = new InputSource (new StringReader (this .stringRep ));
205
+ try {
206
+ XMLReader reader = XMLReaderFactory .createXMLReader ();
207
+ // According to https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
208
+ reader .setFeature (XMLConstants .FEATURE_SECURE_PROCESSING , true );
209
+ setFeature (reader , "http://apache.org/xml/features/disallow-doctype-decl" , true );
210
+ setFeature (reader , "http://apache.org/xml/features/nonvalidating/load-external-dtd" , false );
211
+ setFeature (reader , "http://xml.org/sax/features/external-general-entities" , false );
212
+ setFeature (reader , "http://xml.org/sax/features/external-parameter-entities" , false );
213
+
214
+ return (T ) new SAXSource (reader , this .fromResultSet ? new InputSource (this .owningResultSet .getCharacterStream (this .columnIndexOfXml ))
215
+ : new InputSource (new StringReader (this .stringRep )));
216
+ } catch (SAXException ex ) {
217
+ SQLException sqlEx = SQLError .createSQLException (ex .getMessage (), MysqlErrorNumbers .SQL_STATE_ILLEGAL_ARGUMENT , ex , this .exceptionInterceptor );
218
+ throw sqlEx ;
208
219
}
209
220
210
- return (T ) new SAXSource (inputSource );
211
221
} else if (clazz .equals (DOMSource .class )) {
212
222
try {
213
223
DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance ();
214
224
builderFactory .setNamespaceAware (true );
215
- DocumentBuilder builder = builderFactory .newDocumentBuilder ();
216
225
217
- InputSource inputSource = null ;
226
+ // According to https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
227
+ setFeature (builderFactory , XMLConstants .FEATURE_SECURE_PROCESSING , true );
228
+ setFeature (builderFactory , "http://apache.org/xml/features/disallow-doctype-decl" , true );
229
+ setFeature (builderFactory , "http://xml.org/sax/features/external-general-entities" , false );
230
+ setFeature (builderFactory , "http://xml.org/sax/features/external-parameter-entities" , false );
231
+ setFeature (builderFactory , "http://apache.org/xml/features/nonvalidating/load-external-dtd" , false );
232
+ builderFactory .setXIncludeAware (false );
233
+ builderFactory .setExpandEntityReferences (false );
218
234
219
- if (this .fromResultSet ) {
220
- inputSource = new InputSource (this .owningResultSet .getCharacterStream (this .columnIndexOfXml ));
221
- } else {
222
- inputSource = new InputSource (new StringReader (this .stringRep ));
223
- }
235
+ builderFactory .setAttribute (XMLConstants .ACCESS_EXTERNAL_SCHEMA , "" );
224
236
225
- return (T ) new DOMSource (builder .parse (inputSource ));
237
+ DocumentBuilder builder = builderFactory .newDocumentBuilder ();
238
+
239
+ return (T ) new DOMSource (builder .parse (this .fromResultSet ? new InputSource (this .owningResultSet .getCharacterStream (this .columnIndexOfXml ))
240
+ : new InputSource (new StringReader (this .stringRep ))));
226
241
} catch (Throwable t ) {
227
242
SQLException sqlEx = SQLError .createSQLException (t .getMessage (), MysqlErrorNumbers .SQL_STATE_ILLEGAL_ARGUMENT , t , this .exceptionInterceptor );
228
243
throw sqlEx ;
229
244
}
230
245
231
246
} else if (clazz .equals (StreamSource .class )) {
232
- Reader reader = null ;
233
-
234
- if (this .fromResultSet ) {
235
- reader = this .owningResultSet .getCharacterStream (this .columnIndexOfXml );
236
- } else {
237
- reader = new StringReader (this .stringRep );
238
- }
247
+ return (T ) new StreamSource (this .fromResultSet ? this .owningResultSet .getCharacterStream (this .columnIndexOfXml ) : new StringReader (this .stringRep ));
239
248
240
- return (T ) new StreamSource (reader );
241
249
} else if (clazz .equals (StAXSource .class )) {
242
250
try {
243
- Reader reader = null ;
244
-
245
- if (this .fromResultSet ) {
246
- reader = this .owningResultSet .getCharacterStream (this .columnIndexOfXml );
247
- } else {
248
- reader = new StringReader (this .stringRep );
249
- }
250
-
251
- return (T ) new StAXSource (this .inputFactory .createXMLStreamReader (reader ));
251
+ return (T ) new StAXSource (this .inputFactory .createXMLStreamReader (
252
+ this .fromResultSet ? this .owningResultSet .getCharacterStream (this .columnIndexOfXml ) : new StringReader (this .stringRep )));
252
253
} catch (XMLStreamException ex ) {
253
254
SQLException sqlEx = SQLError .createSQLException (ex .getMessage (), MysqlErrorNumbers .SQL_STATE_ILLEGAL_ARGUMENT , ex , this .exceptionInterceptor );
254
255
throw sqlEx ;
@@ -259,6 +260,18 @@ public <T extends Source> T getSource(Class<T> clazz) throws SQLException {
259
260
}
260
261
}
261
262
263
+ private static void setFeature (Object factory , String name , boolean value ) {
264
+ try {
265
+ if (factory instanceof DocumentBuilderFactory ) {
266
+ ((DocumentBuilderFactory ) factory ).setFeature (name , value );
267
+ } else if (factory instanceof XMLReader ) {
268
+ ((XMLReader ) factory ).setFeature (name , value );
269
+ }
270
+ } catch (Exception ignore ) {
271
+ // no-op
272
+ }
273
+ }
274
+
262
275
@ Override
263
276
public synchronized OutputStream setBinaryStream () throws SQLException {
264
277
checkClosed ();
0 commit comments