Merge pull request #11182 from aschackmull/mad/split-configs

Java/C#: Split active configurations for model generator
This commit is contained in:
Anders Schack-Mulligen
2022-11-09 15:06:43 +01:00
committed by GitHub
10 changed files with 88 additions and 33 deletions

View File

@@ -8,6 +8,10 @@
import internal.CaptureModels
class Activate extends ActiveConfiguration {
override predicate activateToSinkConfig() { any() }
}
from DataFlowTargetApi api, string sink
where sink = captureSink(api)
select sink order by sink

View File

@@ -8,6 +8,10 @@
import internal.CaptureModels
class Activate extends ActiveConfiguration {
override predicate activateFromSourceConfig() { any() }
}
from DataFlowTargetApi api, string source
where source = captureSource(api)
select source order by source

View File

@@ -5,6 +5,14 @@
private import CaptureModelsSpecific
class ActiveConfiguration extends Unit {
predicate activateThroughFlowConfig() { none() }
predicate activateFromSourceConfig() { none() }
predicate activateToSinkConfig() { none() }
}
class DataFlowTargetApi extends TargetApiSpecific {
DataFlowTargetApi() { isRelevantForDataFlowModels(this) }
}
@@ -140,7 +148,9 @@ private class TaintStore extends DataFlow::FlowState {
* This can be used to generate Flow summaries for APIs from parameter to return.
*/
private class ThroughFlowConfig extends TaintTracking::Configuration {
ThroughFlowConfig() { this = "ThroughFlowConfig" }
ThroughFlowConfig() {
this = "ThroughFlowConfig" and any(ActiveConfiguration ac).activateThroughFlowConfig()
}
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof DataFlow::ParameterNode and
@@ -210,7 +220,9 @@ string captureThroughFlow(DataFlowTargetApi api) {
* via its return (then the API itself becomes a source).
*/
private class FromSourceConfiguration extends TaintTracking::Configuration {
FromSourceConfiguration() { this = "FromSourceConfiguration" }
FromSourceConfiguration() {
this = "FromSourceConfiguration" and any(ActiveConfiguration ac).activateFromSourceConfig()
}
override predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) }
@@ -250,8 +262,13 @@ string captureSource(DataFlowTargetApi api) {
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
* into an existing known sink (then the API itself becomes a sink).
*/
private class PropagateToSinkConfiguration extends PropagateToSinkConfigurationSpecific {
PropagateToSinkConfiguration() { this = "parameters or fields flowing into sinks" }
private class PropagateToSinkConfiguration extends TaintTracking::Configuration {
PropagateToSinkConfiguration() {
this = "parameters or fields flowing into sinks" and
any(ActiveConfiguration ac).activateToSinkConfig()
}
override predicate isSource(DataFlow::Node source) { apiSource(source) }
override predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) }

View File

@@ -19,6 +19,8 @@ module TaintTracking = CS::TaintTracking;
class Type = CS::Type;
class Unit = DataFlowPrivate::Unit;
/**
* Holds if any of the parameters of `api` are `System.Func<>`.
*/
@@ -174,15 +176,11 @@ private predicate isRelevantMemberAccess(DataFlow::Node node) {
}
/**
* Language specific parts of the `PropagateToSinkConfiguration`.
* Holds if `source` is an api entrypoint relevant for creating sink models.
*/
class PropagateToSinkConfigurationSpecific extends CS::TaintTracking::Configuration {
PropagateToSinkConfigurationSpecific() { this = "parameters or fields flowing into sinks" }
override predicate isSource(DataFlow::Node source) {
(isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode) and
isRelevantForModels(source.getEnclosingCallable())
}
predicate apiSource(DataFlow::Node source) {
(isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode) and
isRelevantForModels(source.getEnclosingCallable())
}
/**

View File

@@ -1,5 +1,9 @@
private import CaptureModels
private class Activate extends ActiveConfiguration {
override predicate activateThroughFlowConfig() { any() }
}
/**
* Capture fluent APIs that return `this`.
* Example of a fluent API:

View File

@@ -8,6 +8,10 @@
import internal.CaptureModels
class Activate extends ActiveConfiguration {
override predicate activateToSinkConfig() { any() }
}
from DataFlowTargetApi api, string sink
where sink = captureSink(api)
select sink order by sink

View File

@@ -8,6 +8,10 @@
import internal.CaptureModels
class Activate extends ActiveConfiguration {
override predicate activateFromSourceConfig() { any() }
}
from DataFlowTargetApi api, string source
where source = captureSource(api)
select source order by source

View File

@@ -5,6 +5,14 @@
private import CaptureModelsSpecific
class ActiveConfiguration extends Unit {
predicate activateThroughFlowConfig() { none() }
predicate activateFromSourceConfig() { none() }
predicate activateToSinkConfig() { none() }
}
class DataFlowTargetApi extends TargetApiSpecific {
DataFlowTargetApi() { isRelevantForDataFlowModels(this) }
}
@@ -140,7 +148,9 @@ private class TaintStore extends DataFlow::FlowState {
* This can be used to generate Flow summaries for APIs from parameter to return.
*/
private class ThroughFlowConfig extends TaintTracking::Configuration {
ThroughFlowConfig() { this = "ThroughFlowConfig" }
ThroughFlowConfig() {
this = "ThroughFlowConfig" and any(ActiveConfiguration ac).activateThroughFlowConfig()
}
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof DataFlow::ParameterNode and
@@ -210,7 +220,9 @@ string captureThroughFlow(DataFlowTargetApi api) {
* via its return (then the API itself becomes a source).
*/
private class FromSourceConfiguration extends TaintTracking::Configuration {
FromSourceConfiguration() { this = "FromSourceConfiguration" }
FromSourceConfiguration() {
this = "FromSourceConfiguration" and any(ActiveConfiguration ac).activateFromSourceConfig()
}
override predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) }
@@ -250,8 +262,13 @@ string captureSource(DataFlowTargetApi api) {
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
* into an existing known sink (then the API itself becomes a sink).
*/
private class PropagateToSinkConfiguration extends PropagateToSinkConfigurationSpecific {
PropagateToSinkConfiguration() { this = "parameters or fields flowing into sinks" }
private class PropagateToSinkConfiguration extends TaintTracking::Configuration {
PropagateToSinkConfiguration() {
this = "parameters or fields flowing into sinks" and
any(ActiveConfiguration ac).activateToSinkConfig()
}
override predicate isSource(DataFlow::Node source) { apiSource(source) }
override predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) }

View File

@@ -18,6 +18,8 @@ module TaintTracking = Tt::TaintTracking;
class Type = J::Type;
class Unit = J::Unit;
private J::Method superImpl(J::Method m) {
result = m.getAnOverride() and
not exists(result.getAnOverride()) and
@@ -223,24 +225,21 @@ predicate isOwnInstanceAccessNode(ReturnNode node) {
}
/**
* Language specific parts of the `PropagateToSinkConfiguration`.
* Holds if `source` is an api entrypoint relevant for creating sink models.
*/
class PropagateToSinkConfigurationSpecific extends TaintTracking::Configuration {
PropagateToSinkConfigurationSpecific() { this = "parameters or fields flowing into sinks" }
override predicate isSource(DataFlow::Node source) {
(
source.asExpr().(J::FieldAccess).isOwnFieldAccess() or
source instanceof DataFlow::ParameterNode
) and
source.getEnclosingCallable().isPublic() and
exists(J::RefType t |
t = source.getEnclosingCallable().getDeclaringType().getAnAncestor() and
not t instanceof J::TypeObject and
t.isPublic()
) and
isRelevantForModels(source.getEnclosingCallable())
}
predicate apiSource(DataFlow::Node source) {
(
source.asExpr().(J::FieldAccess).isOwnFieldAccess() or
source instanceof DataFlow::ParameterNode
) and
source.getEnclosingCallable().isPublic() and
exists(J::RefType t |
t = source.getEnclosingCallable().getDeclaringType().getAnAncestor() and
not t instanceof J::TypeObject and
t.isPublic()
) and
isRelevantForModels(source.getEnclosingCallable()) and
exists(asPartialModel(source.getEnclosingCallable()))
}
/**

View File

@@ -1,5 +1,9 @@
private import CaptureModels
private class Activate extends ActiveConfiguration {
override predicate activateThroughFlowConfig() { any() }
}
/**
* Capture fluent APIs that return `this`.
* Example of a fluent API: