From 0339bd0f3e7141a59f404423e17a27a800746c3f Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 3 Jan 2025 11:35:38 +0100 Subject: [PATCH 1/6] JS: Deprecate forward/backward exploration modules --- .../ql/lib/semmle/javascript/dataflow/BackwardExploration.qll | 1 + .../ql/lib/semmle/javascript/dataflow/ForwardExploration.qll | 1 + .../ql/lib/semmle/javascript/explore/BackwardDataFlow.qll | 3 ++- .../ql/lib/semmle/javascript/explore/ForwardDataFlow.qll | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/BackwardExploration.qll b/javascript/ql/lib/semmle/javascript/dataflow/BackwardExploration.qll index 54d7927a7f63..bc527b500c96 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/BackwardExploration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/BackwardExploration.qll @@ -1,5 +1,6 @@ /** * Alias for the library `semmle.javascript.explore.BackwardDataFlow`. */ +deprecated module; import semmle.javascript.explore.BackwardDataFlow diff --git a/javascript/ql/lib/semmle/javascript/dataflow/ForwardExploration.qll b/javascript/ql/lib/semmle/javascript/dataflow/ForwardExploration.qll index 44667581eab3..9b9fe218f09d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/ForwardExploration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/ForwardExploration.qll @@ -1,5 +1,6 @@ /** * Alias for the library `semmle.javascript.explore.ForwardDataFlow`. */ +deprecated module; import semmle.javascript.explore.ForwardDataFlow diff --git a/javascript/ql/lib/semmle/javascript/explore/BackwardDataFlow.qll b/javascript/ql/lib/semmle/javascript/explore/BackwardDataFlow.qll index bef34dc8ecdb..18b7c27a2db2 100644 --- a/javascript/ql/lib/semmle/javascript/explore/BackwardDataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/explore/BackwardDataFlow.qll @@ -12,10 +12,11 @@ * Backward exploration in particular does not scale on non-trivial code bases and hence is of limited * usefulness as it stands. */ +deprecated module; import javascript -private class BackwardExploringConfiguration extends DataFlow::Configuration { +deprecated private class BackwardExploringConfiguration extends DataFlow::Configuration { BackwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) } override predicate isSource(DataFlow::Node node) { any() } diff --git a/javascript/ql/lib/semmle/javascript/explore/ForwardDataFlow.qll b/javascript/ql/lib/semmle/javascript/explore/ForwardDataFlow.qll index 4d6368c63b8d..9d435d067b2e 100644 --- a/javascript/ql/lib/semmle/javascript/explore/ForwardDataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/explore/ForwardDataFlow.qll @@ -10,10 +10,11 @@ * * NOTE: This library should only be used for debugging and exploration, not in production code. */ +deprecated module; import javascript -private class ForwardExploringConfiguration extends DataFlow::Configuration { +deprecated private class ForwardExploringConfiguration extends DataFlow::Configuration { ForwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) } override predicate isSink(DataFlow::Node node) { any() } From 25f5ecba255c31d3f2d131f728f914f64479aace Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 3 Jan 2025 11:38:19 +0100 Subject: [PATCH 2/6] JS: Deprecate the Configuration.qll file --- javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll | 1 + javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index bb032596475e..52e10d68ba75 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -67,6 +67,7 @@ * Finally, we build `PathNode`s for all nodes that appear on a path * computed by `onPath`. */ +deprecated module; private import javascript private import internal.FlowSteps diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index ab11e011a7d2..f86d8806304d 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1929,7 +1929,7 @@ module DataFlow { import Nodes import Sources import TypeInference - import Configuration + deprecated import Configuration import TypeTracking import AdditionalFlowSteps import internal.FunctionWrapperSteps From 47cc3c09f539f10f26549f05a086dad133596206 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 7 Jan 2025 10:43:40 +0100 Subject: [PATCH 3/6] JS: Deprecate an import --- .../ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index ff2cbb3d4be1..1711faa4adeb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -5,7 +5,7 @@ */ import javascript -import semmle.javascript.dataflow.Configuration +deprecated import semmle.javascript.dataflow.Configuration import semmle.javascript.dataflow.internal.CallGraphs private import semmle.javascript.internal.CachedStages From f17cc5af15c797200b99afd7afceada97ad70a92 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 7 Jan 2025 10:44:09 +0100 Subject: [PATCH 4/6] JS: Move all hidden node definitions into DataFlowPrivate --- .../javascript/dataflow/Configuration.qll | 35 ++----------------- .../dataflow/internal/DataFlowPrivate.qll | 25 ++++++++++++- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 52e10d68ba75..46479dbec9cd 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -75,6 +75,7 @@ private import internal.AccessPaths private import semmle.javascript.Unit private import semmle.javascript.internal.CachedStages private import AdditionalFlowSteps +private import internal.DataFlowPrivate as DataFlowPrivate /** * A data flow tracking configuration for finding inter-procedural paths from @@ -1794,39 +1795,7 @@ deprecated class MidPathNode extends PathNode, MkMidNode { * Holds if this node is hidden from paths in path explanation queries, except * in cases where it is the source or sink. */ - predicate isHidden() { PathNode::shouldNodeBeHidden(nd) } -} - -/** Companion module to the `PathNode` class. */ -module PathNode { - /** Holds if `nd` should be hidden in data flow paths. */ - predicate shouldNodeBeHidden(DataFlow::Node nd) { - // TODO: move to DataFlowPrivate - // Skip phi, refinement, and capture nodes - nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof - SsaImplicitDefinition - or - // Skip SSA definition of parameter as its location coincides with the parameter node - nd = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p))) - or - // Skip to the top of big left-leaning string concatenation trees. - nd = any(AddExpr add).flow() and - nd = any(AddExpr add).getAnOperand().flow() - or - // Skip the exceptional return on functions, as this highlights the entire function. - nd = any(DataFlow::FunctionNode f).getExceptionalReturn() - or - // Skip the special return node for functions, as this highlights the entire function (and the returned expr is the previous node). - nd = any(DataFlow::FunctionNode f).getReturnNode() - or - // Skip the synthetic 'this' node, as a ThisExpr will be the next node anyway - nd = DataFlow::thisNode(_) - or - // Skip captured variable nodes as the successor will be a use of that variable anyway. - nd = DataFlow::capturedVariableNode(_) - or - nd instanceof DataFlow::FunctionSelfReferenceNode - } + predicate isHidden() { DataFlowPrivate::nodeIsHidden(nd) } } /** diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 72de0f5c0458..862db5f95070 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -604,7 +604,30 @@ DataFlowType getNodeType(Node node) { } predicate nodeIsHidden(Node node) { - DataFlow::PathNode::shouldNodeBeHidden(node) + // Skip phi, refinement, and capture nodes + node.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof + SsaImplicitDefinition + or + // Skip SSA definition of parameter as its location coincides with the parameter node + node = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p))) + or + // Skip to the top of big left-leaning string concatenation trees. + node = any(AddExpr add).flow() and + node = any(AddExpr add).getAnOperand().flow() + or + // Skip the exceptional return on functions, as this highlights the entire function. + node = any(DataFlow::FunctionNode f).getExceptionalReturn() + or + // Skip the special return node for functions, as this highlights the entire function (and the returned expr is the previous node). + node = any(DataFlow::FunctionNode f).getReturnNode() + or + // Skip the synthetic 'this' node, as a ThisExpr will be the next node anyway + node = DataFlow::thisNode(_) + or + // Skip captured variable nodes as the successor will be a use of that variable anyway. + node = DataFlow::capturedVariableNode(_) + or + node instanceof DataFlow::FunctionSelfReferenceNode or node instanceof FlowSummaryNode or From c47419e66d3a5baafbb520aceb0a5251b9b1e311 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 8 Jan 2025 08:54:41 +0100 Subject: [PATCH 5/6] JS: Remove an obsolete TODO comment (this has been fixed) --- javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 46479dbec9cd..314719582ab3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -2006,7 +2006,6 @@ deprecated private class CallAgainstEqualityCheck extends DerivedBarrierGuardNod * Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks. */ class VarAccessBarrier extends DataFlow::Node { - // TODO: This does not work in dataflow2 when the variable is captured, since the capture-flow library bypasses the refinement node. VarAccessBarrier() { exists(ConditionGuardNode guard, SsaRefinementNode refinement | this = DataFlow::ssaDefinitionNode(refinement) and From 36f0d2f63e77cab53614227d76497de7ba53b8a8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 8 Jan 2025 08:55:51 +0100 Subject: [PATCH 6/6] JS: Move VarAccessBarrier outside the deprecated Configuration.qll file --- .../semmle/javascript/dataflow/Configuration.qll | 15 --------------- .../ql/lib/semmle/javascript/dataflow/Nodes.qll | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 314719582ab3..06e3f9e65771 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -2001,21 +2001,6 @@ deprecated private class CallAgainstEqualityCheck extends DerivedBarrierGuardNod override predicate appliesTo(Configuration cfg) { isBarrierGuardInternal(cfg, prev) } } -/** - * A guard node for a variable in a negative condition, such as `x` in `if(!x)`. - * Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks. - */ -class VarAccessBarrier extends DataFlow::Node { - VarAccessBarrier() { - exists(ConditionGuardNode guard, SsaRefinementNode refinement | - this = DataFlow::ssaDefinitionNode(refinement) and - refinement.getGuard() = guard and - guard.getTest() instanceof VarAccess and - guard.getOutcome() = false - ) - } -} - /** * Holds if there is a path without unmatched return steps from `source` to `sink`. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll index 6ef4f6e8b0e5..762fc45333f9 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll @@ -1708,3 +1708,18 @@ class RegExpCreationNode extends DataFlow::SourceNode { result = this.getAReference(DataFlow::TypeTracker::end()) } } + +/** + * A guard node for a variable in a negative condition, such as `x` in `if(!x)`. + * Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks. + */ +class VarAccessBarrier extends DataFlow::Node { + VarAccessBarrier() { + exists(ConditionGuardNode guard, SsaRefinementNode refinement | + this = DataFlow::ssaDefinitionNode(refinement) and + refinement.getGuard() = guard and + guard.getTest() instanceof VarAccess and + guard.getOutcome() = false + ) + } +}