Skip to content

Commit 296c0a7

Browse files
authored
Merge pull request #10603 from asgerf/type-model-api-node
Add TypeModel.getAnApiNode
2 parents cda05ed + 65de5d0 commit 296c0a7

File tree

6 files changed

+74
-3
lines changed

6 files changed

+74
-3
lines changed

javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,27 @@ module ModelInput {
164164
class TypeModel extends Unit {
165165
/**
166166
* Gets a data-flow node that is a source of the type `package;type`.
167+
*
168+
* This must not depend on API graphs, but ensures that an API node is generated for
169+
* the source.
167170
*/
168171
DataFlow::Node getASource(string package, string type) { none() }
169172

170173
/**
171-
* Gets a data flow node that is a sink of the type `package;type`,
174+
* Gets a data-flow node that is a sink of the type `package;type`,
172175
* usually because it is an argument passed to a parameter of that type.
176+
*
177+
* This must not depend on API graphs, but ensures that an API node is generated for
178+
* the sink.
173179
*/
174180
DataFlow::Node getASink(string package, string type) { none() }
181+
182+
/**
183+
* Gets an API node that is a source or sink of the type `package;type`.
184+
*
185+
* Unlike `getASource` and `getASink`, this may depend on API graphs.
186+
*/
187+
API::Node getAnApiNode(string package, string type) { none() }
175188
}
176189

177190
/**
@@ -434,6 +447,8 @@ private API::Node getNodeFromType(string package, string type) {
434447
or
435448
result = any(TypeModelDefEntry e).getNodeForType(package, type)
436449
or
450+
result = any(TypeModel t).getAnApiNode(package, type)
451+
or
437452
result = Specific::getExtraNodeFromType(package, type)
438453
}
439454

python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,27 @@ module ModelInput {
164164
class TypeModel extends Unit {
165165
/**
166166
* Gets a data-flow node that is a source of the type `package;type`.
167+
*
168+
* This must not depend on API graphs, but ensures that an API node is generated for
169+
* the source.
167170
*/
168171
DataFlow::Node getASource(string package, string type) { none() }
169172

170173
/**
171-
* Gets a data flow node that is a sink of the type `package;type`,
174+
* Gets a data-flow node that is a sink of the type `package;type`,
172175
* usually because it is an argument passed to a parameter of that type.
176+
*
177+
* This must not depend on API graphs, but ensures that an API node is generated for
178+
* the sink.
173179
*/
174180
DataFlow::Node getASink(string package, string type) { none() }
181+
182+
/**
183+
* Gets an API node that is a source or sink of the type `package;type`.
184+
*
185+
* Unlike `getASource` and `getASink`, this may depend on API graphs.
186+
*/
187+
API::Node getAnApiNode(string package, string type) { none() }
175188
}
176189

177190
/**
@@ -434,6 +447,8 @@ private API::Node getNodeFromType(string package, string type) {
434447
or
435448
result = any(TypeModelDefEntry e).getNodeForType(package, type)
436449
or
450+
result = any(TypeModel t).getAnApiNode(package, type)
451+
or
437452
result = Specific::getExtraNodeFromType(package, type)
438453
}
439454

ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,27 @@ module ModelInput {
164164
class TypeModel extends Unit {
165165
/**
166166
* Gets a data-flow node that is a source of the type `package;type`.
167+
*
168+
* This must not depend on API graphs, but ensures that an API node is generated for
169+
* the source.
167170
*/
168171
DataFlow::Node getASource(string package, string type) { none() }
169172

170173
/**
171-
* Gets a data flow node that is a sink of the type `package;type`,
174+
* Gets a data-flow node that is a sink of the type `package;type`,
172175
* usually because it is an argument passed to a parameter of that type.
176+
*
177+
* This must not depend on API graphs, but ensures that an API node is generated for
178+
* the sink.
173179
*/
174180
DataFlow::Node getASink(string package, string type) { none() }
181+
182+
/**
183+
* Gets an API node that is a source or sink of the type `package;type`.
184+
*
185+
* Unlike `getASource` and `getASink`, this may depend on API graphs.
186+
*/
187+
API::Node getAnApiNode(string package, string type) { none() }
175188
}
176189

177190
/**
@@ -434,6 +447,8 @@ private API::Node getNodeFromType(string package, string type) {
434447
or
435448
result = any(TypeModelDefEntry e).getNodeForType(package, type)
436449
or
450+
result = any(TypeModel t).getAnApiNode(package, type)
451+
or
437452
result = Specific::getExtraNodeFromType(package, type)
438453
}
439454

ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ edges
3434
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:128:26:128:32 | tainted |
3535
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:130:23:130:29 | tainted |
3636
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:130:23:130:29 | tainted |
37+
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:133:19:133:25 | tainted |
38+
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:133:19:133:25 | tainted |
39+
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:134:19:134:25 | tainted |
40+
| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:134:19:134:25 | tainted |
3741
| summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : |
3842
| summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : |
3943
| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:9:6:9:13 | tainted2 |
@@ -186,6 +190,8 @@ edges
186190
| summaries.rb:115:16:115:22 | [post] tainted : | summaries.rb:125:21:125:27 | tainted |
187191
| summaries.rb:115:16:115:22 | [post] tainted : | summaries.rb:128:26:128:32 | tainted |
188192
| summaries.rb:115:16:115:22 | [post] tainted : | summaries.rb:130:23:130:29 | tainted |
193+
| summaries.rb:115:16:115:22 | [post] tainted : | summaries.rb:133:19:133:25 | tainted |
194+
| summaries.rb:115:16:115:22 | [post] tainted : | summaries.rb:134:19:134:25 | tainted |
189195
| summaries.rb:115:16:115:22 | tainted : | summaries.rb:115:16:115:22 | [post] tainted : |
190196
| summaries.rb:115:16:115:22 | tainted : | summaries.rb:115:25:115:25 | [post] y : |
191197
| summaries.rb:115:16:115:22 | tainted : | summaries.rb:115:33:115:33 | [post] z : |
@@ -387,6 +393,10 @@ nodes
387393
| summaries.rb:128:26:128:32 | tainted | semmle.label | tainted |
388394
| summaries.rb:130:23:130:29 | tainted | semmle.label | tainted |
389395
| summaries.rb:130:23:130:29 | tainted | semmle.label | tainted |
396+
| summaries.rb:133:19:133:25 | tainted | semmle.label | tainted |
397+
| summaries.rb:133:19:133:25 | tainted | semmle.label | tainted |
398+
| summaries.rb:134:19:134:25 | tainted | semmle.label | tainted |
399+
| summaries.rb:134:19:134:25 | tainted | semmle.label | tainted |
390400
subpaths
391401
invalidSpecComponent
392402
#select
@@ -474,6 +484,10 @@ invalidSpecComponent
474484
| summaries.rb:128:26:128:32 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:128:26:128:32 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
475485
| summaries.rb:130:23:130:29 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:130:23:130:29 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
476486
| summaries.rb:130:23:130:29 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:130:23:130:29 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
487+
| summaries.rb:133:19:133:25 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:133:19:133:25 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
488+
| summaries.rb:133:19:133:25 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:133:19:133:25 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
489+
| summaries.rb:134:19:134:25 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:134:19:134:25 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
490+
| summaries.rb:134:19:134:25 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:134:19:134:25 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
477491
warning
478492
| CSV type row should have 5 columns but has 2: test;TooFewColumns |
479493
| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns |

ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import codeql.ruby.AST
6+
import codeql.ruby.ApiGraphs
67
import codeql.ruby.dataflow.FlowSummary
78
import codeql.ruby.TaintTracking
89
import codeql.ruby.dataflow.internal.FlowSummaryImpl
@@ -112,6 +113,12 @@ private class TypeFromCodeQL extends ModelInput::TypeModel {
112113
type = "FooOrBar" and
113114
result.asExpr().getExpr().getConstantValue().getString() = "magic_string"
114115
}
116+
117+
override API::Node getAnApiNode(string package, string type) {
118+
package = "test" and
119+
type = "FooOrBar" and
120+
result = API::getTopLevelMember("Alias").getMember(["Foo", "Bar"])
121+
}
115122
}
116123

117124
private class InvalidTypeModel extends ModelInput::TypeModelCsv {

ruby/ql/test/library-tests/dataflow/summaries/summaries.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,8 @@ def userDefinedFunction(x, y)
129129

130130
"magic_string".method(tainted) # $ hasValueFlow=tainted
131131
"magic_string2".method(tainted)
132+
133+
Alias::Foo.method(tainted) # $ hasValueFlow=tainted
134+
Alias::Bar.method(tainted) # $ hasValueFlow=tainted
135+
Something::Foo.method(tainted)
136+
Alias::Something.method(tainted)

0 commit comments

Comments
 (0)