-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Python: Add jump steps for global variable nested field access #20162
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
Changes from all commits
f209e3a
6c779c7
9d4b168
e60d0c8
69b5853
6133f01
8393ccf
6f9e06c
e228aac
e82fe9d
431fc88
8fd6225
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| category: minorAnalysis | ||
| --- | ||
| * Data flow tracking through global variables now supports nested field access patterns such as `global_var.obj.field`. This improves the precision of taint tracking analysis when data flows through complex global variable structures. |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -556,6 +556,75 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) { | |||||||||||||
| nodeFrom.asCfgNode() = param.getDefault() and | ||||||||||||||
| nodeTo.asCfgNode() = param.getDefiningNode() | ||||||||||||||
| ) | ||||||||||||||
| or | ||||||||||||||
| // Enhanced global variable field access tracking | ||||||||||||||
| globalVariableNestedFieldJumpStep(nodeFrom, nodeTo) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** Helper predicate for `globalVariableNestedFieldJumpStep`. */ | ||||||||||||||
| pragma[nomagic] | ||||||||||||||
| private predicate globalVariableAttrPathRead( | ||||||||||||||
| ModuleVariableNode globalVar, string accessPath, AttrRead r, string attrName | ||||||||||||||
| ) { | ||||||||||||||
| globalVariableAttrPathAtDepth(globalVar, accessPath, r.getObject(), _) and | ||||||||||||||
| attrName = r.getAttributeName() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** Helper predicate for `globalVariableNestedFieldJumpStep`. */ | ||||||||||||||
| pragma[nomagic] | ||||||||||||||
| private predicate globalVariableAttrPathWrite( | ||||||||||||||
| ModuleVariableNode globalVar, string accessPath, AttrWrite w, string attrName | ||||||||||||||
| ) { | ||||||||||||||
| globalVariableAttrPathAtDepth(globalVar, accessPath, w.getObject(), _) and | ||||||||||||||
| attrName = w.getAttributeName() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Holds if there is a jump step from `nodeFrom` to `nodeTo` through global variable field access. | ||||||||||||||
| * This supports tracking nested object field access through global variables like `app.obj.foo`. | ||||||||||||||
| */ | ||||||||||||||
| pragma[nomagic] | ||||||||||||||
| private predicate globalVariableNestedFieldJumpStep(Node nodeFrom, Node nodeTo) { | ||||||||||||||
| exists(ModuleVariableNode globalVar, AttrWrite write, AttrRead read | | ||||||||||||||
| // Match writes and reads on the same global variable attribute path | ||||||||||||||
| exists(string accessPath, string attrName | | ||||||||||||||
| globalVariableAttrPathRead(globalVar, accessPath, read, attrName) and | ||||||||||||||
| globalVariableAttrPathWrite(globalVar, accessPath, write, attrName) | ||||||||||||||
| ) and | ||||||||||||||
| nodeFrom = write.getValue() and | ||||||||||||||
| nodeTo = read | ||||||||||||||
| ) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Maximum depth for global variable nested attribute access. | ||||||||||||||
| * Depth 1 = globalVar.foo, depth 2 = globalVar.foo.bar, depth 3 = globalVar.foo.bar.baz, etc. | ||||||||||||||
| */ | ||||||||||||||
| private int getMaxGlobalVariableDepth() { result = 2 } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Holds if `node` is an attribute access path starting from global variable `globalVar` at specific `depth`. | ||||||||||||||
| */ | ||||||||||||||
| private predicate globalVariableAttrPathAtDepth( | ||||||||||||||
| ModuleVariableNode globalVar, string accessPath, Node node, int depth | ||||||||||||||
| ) { | ||||||||||||||
| // Base case: Direct global variable access (depth 0) | ||||||||||||||
| depth = 0 and | ||||||||||||||
| // We use `globalVar` instead of `globalVar.getAWrite()` due to some weirdness with how | ||||||||||||||
| // attribute writes are handled in the global scope (see `GlobalAttributeAssignmentAsAttrWrite`). | ||||||||||||||
|
||||||||||||||
| // attribute writes are handled in the global scope (see `GlobalAttributeAssignmentAsAttrWrite`). | |
| // We use `globalVar` instead of `globalVar.getAWrite()` because global attribute assignments | |
| // in the global scope are not always represented as `AttrWrite` nodes by the extractor. | |
| // Specifically, `GlobalAttributeAssignmentAsAttrWrite` models some global attribute assignments | |
| // differently, so `getAWrite()` does not reliably capture all such cases. This ensures that | |
| // both direct global variable accesses and global attribute assignments are handled correctly. |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The maximum depth is hardcoded to 2. Consider making this configurable through a parameter or constant that can be easily adjusted without modifying the predicate, especially since the feature description mentions 'configurable depth limit'.