CodeQL to get python attribute and corresponding definition #12313
-
Hi, I would like to get the class definition for a python attribute usage -
My actual goal if to find out usages of AdressData address field which are leaked to logs, but after upgrading Xodeql I can't get my query to work - I had this ql
which found results when I used the older version of codeql (codeql/python-all: "0.6.4" ) , but when upgrading it stopped working.... |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hi, using
Once this is done, I have commented the code a bit, but feel free to ask further questions :-) import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.ApiGraphs
class AddressData extends API::EntryPoint {
AddressData() { this = "AddressData" }
override DataFlow::LocalSourceNode getASource() {
result.asExpr().(ClassExpr).getName() = "AddressData"
}
// Handles the decorator `@dataclass`
API::Node getDataclass() {
exists(API::CallNode decorate |
// decoration happens when invoking the `@dataclass` decorator
decorate = API::moduleImport("dataclasses").getMember("dataclass").getACall() and
// the first argument to the decorator is the `AddressData` class
decorate.getArg(0) = this.getASource() and
// the decorated class is the result of the decorator
result = decorate.getReturn()
)
}
}
from API::Node address, API::CallNode warning
where
// take the data class, instantiate it and get the `address` field
address = any(AddressData ad).getDataclass().getReturn().getMember("address") and
// create a logger and call `warning` (you could add a list of interesting method names here)
warning =
API::moduleImport("logging").getMember("getLogger").getReturn().getMember("warning").getACall() and
// require the `address` field to be and argument to the call to `warning`
warning.getArg(_) = address.getAValueReachableFromSource()
select warning |
Beta Was this translation helpful? Give feedback.
-
What's the way to connect a ClassExpression to attribute for a non-dataclass in a similiar way? |
Beta Was this translation helpful? Give feedback.
Hi, using
Value
is considered old-fashion these days, I suggest you use the API graph instead.You are facing two complications:
AddressData
below does this.getDataclass
does this.Once this is done,
any(AddressData ad).getDataclass().getReturn()
will matchad = AddressData("my address")
(becausegetReturn
matches the act of instantiating the class) and we can go from there.I have commented the code a bit, but feel free to ask further questions :-)