@@ -275,13 +275,38 @@ private module Lxml {
275275 }
276276 }
277277
278+ /**
279+ * A call to `lxml.etree.ElementTree.parse` or `lxml.etree.ElementTree.parseid`, which
280+ * takes either a filename or a file-like object as argument. To capture the filename
281+ * for path-injection, we have this subclass.
282+ *
283+ * See
284+ * - https://lxml.de/apidoc/lxml.etree.html?highlight=parseids#lxml.etree.parse
285+ * - https://lxml.de/apidoc/lxml.etree.html?highlight=parseids#lxml.etree.parseid
286+ */
287+ private class FileAccessFromLXMLParsing extends LXMLParsing , FileSystemAccess:: Range {
288+ FileAccessFromLXMLParsing ( ) {
289+ this = API:: moduleImport ( "lxml" ) .getMember ( "etree" ) .getMember ( [ "parse" , "parseid" ] ) .getACall ( )
290+ // I considered whether we should try to reduce FPs from people passing file-like
291+ // objects, which will not be a file system access (and couldn't cause a
292+ // path-injection).
293+ //
294+ // I suppose that once we have proper flow-summary support for file-like objects,
295+ // we can make the XXE/XML-bomb sinks allow an access-path, while the
296+ // path-injection sink wouldn't, and then we will not end up with such FPs.
297+ }
298+
299+ override DataFlow:: Node getAPathArgument ( ) { result = this .getAnInput ( ) }
300+ }
301+
278302 /**
279303 * A call to `lxml.etree.iterparse`
280304 *
281305 * See
282306 * - https://lxml.de/apidoc/lxml.etree.html?highlight=parseids#lxml.etree.iterparse
283307 */
284- private class LXMLIterparseCall extends DataFlow:: CallCfgNode , XML:: XMLParsing:: Range {
308+ private class LXMLIterparseCall extends DataFlow:: CallCfgNode , XML:: XMLParsing:: Range ,
309+ FileSystemAccess:: Range {
285310 LXMLIterparseCall ( ) {
286311 this = API:: moduleImport ( "lxml" ) .getMember ( "etree" ) .getMember ( "iterparse" ) .getACall ( )
287312 }
@@ -303,5 +328,7 @@ private module Lxml {
303328 override predicate mayExecuteInput ( ) { none ( ) }
304329
305330 override DataFlow:: Node getOutput ( ) { result = this }
331+
332+ override DataFlow:: Node getAPathArgument ( ) { result = this .getAnInput ( ) }
306333 }
307334}
0 commit comments