@@ -53,11 +53,21 @@ private module Xml {
5353 API:: moduleImport ( "xml" )
5454 .getMember ( "etree" )
5555 .getMember ( "ElementTree" )
56- .getMember ( [ "fromstring" , "fromstringlist" , "XML" , "parse" ] )
56+ .getMember ( [ "fromstring" , "fromstringlist" , "XML" , "XMLID" , " parse" , "iterparse "] )
5757 .getACall ( )
5858 }
5959
60- override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
60+ override DataFlow:: Node getAnInput ( ) {
61+ result in [
62+ this .getArg ( 0 ) ,
63+ // fromstring / XML / XMLID
64+ this .getArgByName ( "text" ) ,
65+ // fromstringlist
66+ this .getArgByName ( "sequence" ) ,
67+ // parse / iterparse
68+ this .getArgByName ( "source" ) ,
69+ ]
70+ }
6171
6272 override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
6373 not exists ( this .getArgByName ( "parser" ) ) and
@@ -163,8 +173,8 @@ private module Xml {
163173 * parsed_xml = BadHandler._result
164174 * ```
165175 */
166- private class XMLSaxParsing extends DataFlow:: MethodCallNode , XML:: XMLParsing:: Range {
167- XMLSaxParsing ( ) {
176+ private class XMLSaxInstanceParsing extends DataFlow:: MethodCallNode , XML:: XMLParsing:: Range {
177+ XMLSaxInstanceParsing ( ) {
168178 this =
169179 API:: moduleImport ( "xml" )
170180 .getMember ( "sax" )
@@ -174,7 +184,40 @@ private module Xml {
174184 .getACall ( )
175185 }
176186
177- override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
187+ override DataFlow:: Node getAnInput ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "source" ) ] }
188+
189+ override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
190+ // always vuln to these
191+ ( kind .isBillionLaughs ( ) or kind .isQuadraticBlowup ( ) )
192+ or
193+ // can be vuln to other things if features has been turned on
194+ this .getObject ( ) = saxParserWithFeatureExternalGesTurnedOn ( ) and
195+ ( kind .isXxe ( ) or kind .isDtdRetrieval ( ) )
196+ }
197+ }
198+
199+ /**
200+ * A call to either `parse` or `parseString` from `xml.sax` module.
201+ *
202+ * See:
203+ * - https://docs.python.org/3.10/library/xml.sax.html#xml.sax.parse
204+ * - https://docs.python.org/3.10/library/xml.sax.html#xml.sax.parseString
205+ */
206+ private class XMLSaxParsing extends DataFlow:: MethodCallNode , XML:: XMLParsing:: Range {
207+ XMLSaxParsing ( ) {
208+ this =
209+ API:: moduleImport ( "xml" ) .getMember ( "sax" ) .getMember ( [ "parse" , "parseString" ] ) .getACall ( )
210+ }
211+
212+ override DataFlow:: Node getAnInput ( ) {
213+ result in [
214+ this .getArg ( 0 ) ,
215+ // parseString
216+ this .getArgByName ( "string" ) ,
217+ // parse
218+ this .getArgByName ( "source" ) ,
219+ ]
220+ }
178221
179222 override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
180223 // always vuln to these
@@ -262,11 +305,21 @@ private module Xml {
262305 this =
263306 API:: moduleImport ( "lxml" )
264307 .getMember ( "etree" )
265- .getMember ( [ "fromstring" , "fromstringlist" , "XML" , "parse" ] )
308+ .getMember ( [ "fromstring" , "fromstringlist" , "XML" , "parse" , "parseid" ] )
266309 .getACall ( )
267310 }
268311
269- override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
312+ override DataFlow:: Node getAnInput ( ) {
313+ result in [
314+ this .getArg ( 0 ) ,
315+ // fromstring / XML
316+ this .getArgByName ( "text" ) ,
317+ // fromstringlist
318+ this .getArgByName ( "strings" ) ,
319+ // parse / parseid
320+ this .getArgByName ( "source" ) ,
321+ ]
322+ }
270323
271324 override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
272325 exists ( XML:: XMLParser xmlParser |
@@ -293,7 +346,9 @@ private module Xml {
293346 private class XMLtoDictParsing extends DataFlow:: CallCfgNode , XML:: XMLParsing:: Range {
294347 XMLtoDictParsing ( ) { this = API:: moduleImport ( "xmltodict" ) .getMember ( "parse" ) .getACall ( ) }
295348
296- override DataFlow:: Node getAnInput ( ) { result = this .getArg ( 0 ) }
349+ override DataFlow:: Node getAnInput ( ) {
350+ result in [ this .getArg ( 0 ) , this .getArgByName ( "xml_input" ) ]
351+ }
297352
298353 override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
299354 ( kind .isBillionLaughs ( ) or kind .isQuadraticBlowup ( ) ) and
@@ -317,7 +372,15 @@ private module Xml {
317372 }
318373
319374 override DataFlow:: Node getAnInput ( ) {
320- result in [ this .getArg ( 0 ) , this .getArgByName ( "string" ) , this .getArgByName ( "file" ) ]
375+ result in [
376+ this .getArg ( 0 ) ,
377+ // parseString
378+ this .getArgByName ( "string" ) ,
379+ // minidom.parse
380+ this .getArgByName ( "file" ) ,
381+ // pulldom.parse
382+ this .getArgByName ( "stream_or_string" ) ,
383+ ]
321384 }
322385
323386 DataFlow:: Node getParserArg ( ) { result in [ this .getArg ( 1 ) , this .getArgByName ( "parser" ) ] }
0 commit comments