github / codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
https://codeql.github.com
MIT License
7.75k stars 1.56k forks source link

Python: Dataflow fails when Class attributes are accessed as Instance attributes. #16501

Open trentn opened 6 months ago

trentn commented 6 months ago

I'm testing out dataflow and taint tracking analysis on Python and I've run into a example where the dataflow analysis should find a path, but fails because a class variable is accessed as an instance variable.

Here is the dataflow query

/**
 * @name Testing
 * @kind path-problem
 * @id test
 */

import python
import semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.ApiGraphs

module MyFlowConfiguration implements DataFlow::ConfigSig {
    predicate isSource(DataFlow::Node source) {
        source = API::builtin("input").getACall().getReturn().asSource()
    }

    predicate isSink(DataFlow::Node sink) {
        sink = API::builtin("print").getACall().getAParameter().asSink()
    }
}

module MyFlow = DataFlow::Global<MyFlowConfiguration>;
import MyFlow::PathGraph

from MyFlow::PathNode source, MyFlow::PathNode sink
where MyFlow::flowPath(source,sink)
select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(),
  "user-provided value"

The query correctly identfies the path from input() to print() in this snippet:

class Test():
    def __init__(self):
        self.one = input()

class Test2():
    t = Test
    def func(self):
        test = Test2.t()
        print(test.one)

Test2().func()

But it fails for this snippet:

class Test():
    def __init__(self):
        self.one = input()

class Test2():
    t = Test
    def func(self):
        test = self.t()
        print(test.one)

Test2().func()

The only difference is that the first example uses test = Test2.t() and the second example uses test = self.t() in the function func defined in Test2

This seems related to #14842, #14899 and https://github.com/github/codeql/discussions/9684

mbg commented 6 months ago

Hi @trentn 👋

Thanks for reporting this. I have passed this on to our Python team for them to have a look at it.

RasmusWL commented 6 months ago

Thanks for your detailed report. I have something in the works that should fix this, will update this issue once I publish my PR :+1:

RasmusWL commented 5 months ago

PR up here: https://github.com/github/codeql/pull/16670