diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll index 002a5c8fe8ea..e6d09981a752 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/AdaptiveThreatModeling.qll @@ -34,7 +34,7 @@ module ATM { */ pragma[inline] float getScoreForFlow(DataFlow::Node source, DataFlow::Node sink) { - any(DataFlow::Configuration cfg).hasFlow(source, sink) and + Optimizations::hasFlow(source, sink) and shouldResultBeIncluded(source, sink) and result = unique(float s | s = any(ScoringResults results).getScoreForFlow(source, sink)) } @@ -121,4 +121,26 @@ module ATM { ) } } + + /** + * Predicates for performance improvements that should not affect the semantics. + */ + module Optimizations { + /** + * EXPERIMENTAL. This API may change in the future. + * + * Holds if data may flow from `source` to `sink` for *some* configuration. + * + * This is a variant of `Configuration::hasFlow`, that does not require the precense of a source and a sink. + */ + predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + exists(DataFlow::Configuration cfg | + exists(DataFlow::SourcePathNode flowsource, DataFlow::SinkPathNode flowsink | + cfg.hasFlowPath(flowsource, flowsink) and + source = flowsource.getNode() and + sink = flowsink.getNode() + ) + ) + } + } } diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll index a0d7fd528d3e..f3906e7dfb84 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointScoring.qll @@ -9,6 +9,7 @@ private import BaseScoring private import EndpointFeatures as EndpointFeatures private import FeaturizationConfig private import EndpointTypes +private import AdaptiveThreatModeling private string getACompatibleModelChecksum() { availableMlModels(result, "javascript", _, "atm-endpoint-scoring") @@ -23,9 +24,11 @@ module ModelScoring { RelevantFeaturizationConfig() { this = "RelevantFeaturization" } override DataFlow::Node getAnEndpointToFeaturize() { - getCfg().isEffectiveSource(result) and any(DataFlow::Configuration cfg).hasFlow(result, _) + getCfg().isEffectiveSource(result) and + ATM::Optimizations::hasFlow(result, _) or - getCfg().isEffectiveSink(result) and any(DataFlow::Configuration cfg).hasFlow(_, result) + getCfg().isEffectiveSink(result) and + ATM::Optimizations::hasFlow(_, result) } } @@ -146,7 +149,7 @@ module Debugging { query predicate endpointScores = ModelScoring::endpointScores/3; query predicate shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) { - any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink) and - any(DataFlow::Configuration cfg).hasFlow(source, sink) + ATM::Optimizations::hasFlow(source, sink) and + any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink) } }