@@ -79,6 +79,28 @@ private module Xml {
7979 }
8080 }
8181
82+ /**
83+ * A call to the `feed` method of an `xml.etree` parser.
84+ */
85+ private class XMLEtreeParserFeedCall extends DataFlow:: CallCfgNode , XML:: XMLParsing:: Range {
86+ XMLEtreeParserFeedCall ( ) {
87+ this =
88+ API:: moduleImport ( "xml" )
89+ .getMember ( "etree" )
90+ .getMember ( "ElementTree" )
91+ .getMember ( "XMLParser" )
92+ .getReturn ( )
93+ .getMember ( "feed" )
94+ .getACall ( )
95+ }
96+
97+ override DataFlow:: Node getAnInput ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "data" ) ] }
98+
99+ override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
100+ kind .isBillionLaughs ( ) or kind .isQuadraticBlowup ( )
101+ }
102+ }
103+
82104 /**
83105 * A call to the `setFeature` method on a XML sax parser.
84106 *
@@ -322,6 +344,7 @@ private module Xml {
322344 }
323345
324346 override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
347+ // TODO: This should be done with type-tracking
325348 exists ( XML:: XMLParser xmlParser |
326349 xmlParser = this .getArgByName ( "parser" ) .getALocalSource ( ) and xmlParser .vulnerable ( kind )
327350 )
@@ -330,6 +353,33 @@ private module Xml {
330353 }
331354 }
332355
356+ /**
357+ * A call to the `feed` method of an `lxml.etree` parser.
358+ */
359+ private class LXMLEtreeParserFeedCall extends DataFlow:: MethodCallNode , XML:: XMLParsing:: Range {
360+ LXMLEtreeParserFeedCall ( ) {
361+ exists ( API:: Node parserInstance |
362+ parserInstance =
363+ API:: moduleImport ( "lxml" ) .getMember ( "etree" ) .getMember ( "XMLParser" ) .getReturn ( )
364+ or
365+ parserInstance =
366+ API:: moduleImport ( "lxml" ) .getMember ( "etree" ) .getMember ( "get_default_parser" ) .getReturn ( )
367+ |
368+ this = parserInstance .getMember ( "feed" ) .getACall ( )
369+ )
370+ }
371+
372+ override DataFlow:: Node getAnInput ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "data" ) ] }
373+
374+ override predicate vulnerable ( XML:: XMLVulnerabilityKind kind ) {
375+ // TODO: This should be done with type-tracking
376+ exists ( XML:: XMLParser xmlParser |
377+ xmlParser = this .getObject ( ) .getALocalSource ( ) and
378+ xmlParser .vulnerable ( kind )
379+ )
380+ }
381+ }
382+
333383 /**
334384 * Gets a call to `xmltodict.parse`.
335385 *
0 commit comments