diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll index 72de0f5c0458..8629288f3309 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/DataFlowPrivate.qll @@ -612,6 +612,8 @@ predicate nodeIsHidden(Node node) { or node instanceof FlowSummaryIntermediateAwaitStoreNode or + node instanceof FlowSummaryDefaultExceptionalReturn + or node instanceof CaptureNode or // Hide function expressions, as capture-flow causes them to appear in unhelpful ways diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll index 71603d38ecd6..009367f4f87d 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExceptionXssQuery.qll @@ -153,6 +153,8 @@ module ExceptionXssConfig implements DataFlow::StateConfigSig { canThrowSensitiveInformation(node1) and node2 = getExceptionTarget(node1) } + + int accessPathLimit() { result = 1 } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll index f148ba2c96bb..e516167a30b4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallCustomizations.qll @@ -182,7 +182,11 @@ module UnvalidatedDynamicMethodCall { exists(InvokeExpr invk | this = invk.getCallee().flow() and // don't flag invocations inside a try-catch - not invk.getASuccessor() instanceof CatchClause + not invk.getASuccessor() instanceof CatchClause and + // Filter out `foo.bar()` calls as they usually aren't interesting. + // Technically this could be reachable if preceded by `foo.bar = obj[taint]` + // but such sinks are more likely to be FPs and also slow down the query. + not invk.getCallee() instanceof DotExpr ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll index d8b29fca9014..399d4852cc50 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll @@ -24,6 +24,17 @@ deprecated private class ConcreteMaybeFromProto extends MaybeFromProto { ConcreteMaybeFromProto() { this = this } } +/** Gets a data flow node referring to an instance of `Map`. */ +private DataFlow::SourceNode mapObject(DataFlow::TypeTracker t) { + t.start() and + result = DataFlow::globalVarRef("Map").getAnInstantiation() + or + exists(DataFlow::TypeTracker t2 | result = mapObject(t2).track(t2, t)) +} + +/** Gets a data flow node referring to an instance of `Map`. */ +private DataFlow::SourceNode mapObject() { result = mapObject(DataFlow::TypeTracker::end()) } + /** * A taint-tracking configuration for reasoning about unvalidated dynamic method calls. */ @@ -67,7 +78,9 @@ module UnvalidatedDynamicMethodCallConfig implements DataFlow::StateConfigSig { not PropertyInjection::hasUnsafeMethods(read.getBase().getALocalSource()) ) or - exists(DataFlow::SourceNode base, DataFlow::CallNode get | get = base.getAMethodCall("get") | + exists(DataFlow::CallNode get | + get = mapObject().getAMethodCall("get") and + get.getNumArgument() = 1 and node1 = get.getArgument(0) and node2 = get ) and diff --git a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql index ba7c6d177cbb..2a49f47379ce 100644 --- a/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql +++ b/javascript/ql/src/Security/CWE-915/PrototypePollutingFunction.ql @@ -277,6 +277,12 @@ module PropNameTrackingConfig implements DataFlow::StateConfigSig { node instanceof DataFlow::VarAccessBarrier or node = DataFlow::MakeBarrierGuard::getABarrierNode() } + + int accessPathLimit() { + // Speed up the query. For the pattern we're looking for the value rarely + // flows through any contents, apart from a capture content. + result = 1 + } } class FlowState = PropNameTrackingConfig::FlowState;