Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
trentn opened this issue May 15, 2024 · 2 comments
Assignees
Labels
Python question Further information is requested

Comments

@trentn
Copy link

trentn commented May 15, 2024

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 #9684

@trentn trentn added the question Further information is requested label May 15, 2024
@mbg mbg self-assigned this May 15, 2024
@mbg
Copy link
Member

mbg commented May 15, 2024

Hi @trentn 👋

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

@RasmusWL
Copy link
Member

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

@sidshank sidshank assigned RasmusWL and unassigned mbg Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Python question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants