diff --git a/csharp/ql/src/utils/model-generator/CaptureSinkModels.ql b/csharp/ql/src/utils/model-generator/CaptureSinkModels.ql index ea249016427..04942aa36cc 100644 --- a/csharp/ql/src/utils/model-generator/CaptureSinkModels.ql +++ b/csharp/ql/src/utils/model-generator/CaptureSinkModels.ql @@ -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 diff --git a/csharp/ql/src/utils/model-generator/CaptureSourceModels.ql b/csharp/ql/src/utils/model-generator/CaptureSourceModels.ql index 72ce31d4b61..65ea96c3003 100644 --- a/csharp/ql/src/utils/model-generator/CaptureSourceModels.ql +++ b/csharp/ql/src/utils/model-generator/CaptureSourceModels.ql @@ -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 diff --git a/csharp/ql/src/utils/model-generator/internal/CaptureModels.qll b/csharp/ql/src/utils/model-generator/internal/CaptureModels.qll index 82ac94c8fc4..51cf0dcd2c3 100644 --- a/csharp/ql/src/utils/model-generator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/model-generator/internal/CaptureModels.qll @@ -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, _) } diff --git a/csharp/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll index bd8b227e76f..461148bf5eb 100644 --- a/csharp/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll @@ -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()) } /** diff --git a/csharp/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll b/csharp/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll index e06ea1a609a..2f16baec794 100644 --- a/csharp/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll +++ b/csharp/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll @@ -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: diff --git a/java/ql/src/utils/model-generator/CaptureSinkModels.ql b/java/ql/src/utils/model-generator/CaptureSinkModels.ql index 154c87928fc..740e5aa119a 100644 --- a/java/ql/src/utils/model-generator/CaptureSinkModels.ql +++ b/java/ql/src/utils/model-generator/CaptureSinkModels.ql @@ -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 diff --git a/java/ql/src/utils/model-generator/CaptureSourceModels.ql b/java/ql/src/utils/model-generator/CaptureSourceModels.ql index 8c7de037a90..77a00602f3f 100644 --- a/java/ql/src/utils/model-generator/CaptureSourceModels.ql +++ b/java/ql/src/utils/model-generator/CaptureSourceModels.ql @@ -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 diff --git a/java/ql/src/utils/model-generator/internal/CaptureModels.qll b/java/ql/src/utils/model-generator/internal/CaptureModels.qll index 82ac94c8fc4..51cf0dcd2c3 100644 --- a/java/ql/src/utils/model-generator/internal/CaptureModels.qll +++ b/java/ql/src/utils/model-generator/internal/CaptureModels.qll @@ -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, _) } diff --git a/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll index 2e630ec5214..9aed8ddf2ba 100644 --- a/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll @@ -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())) } /** diff --git a/java/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll b/java/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll index dce9ce9cfef..4b5293e63cd 100644 --- a/java/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll +++ b/java/ql/src/utils/model-generator/internal/CaptureSummaryFlow.qll @@ -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: