@@ -9,7 +9,6 @@ private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
99private import semmle.javascript.security.dataflow.TaintedPathCustomizations
1010private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics
1111private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles
12- private import StandardEndpointFilters as StandardEndpointFilters
1312private import semmle.javascript.security.dataflow.XxeCustomizations
1413private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations
1514private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations
@@ -155,6 +154,53 @@ private predicate isKnownStepSrc(DataFlow::Node n) {
155154 DataFlow:: SharedFlowStep:: step ( n , _, _, _)
156155}
157156
157+ /**
158+ * Holds if the data flow node is a (possibly indirect) argument of a likely external library call.
159+ *
160+ * This includes direct arguments of likely external library calls as well as nested object
161+ * literals within those calls.
162+ */
163+ private predicate flowsToArgumentOfLikelyExternalLibraryCall ( DataFlow:: Node n ) {
164+ n = getACallWithoutCallee ( ) .getAnArgument ( )
165+ or
166+ exists ( DataFlow:: SourceNode src | flowsToArgumentOfLikelyExternalLibraryCall ( src ) |
167+ n = src .getAPropertyWrite ( ) .getRhs ( )
168+ )
169+ or
170+ exists ( DataFlow:: ArrayCreationNode arr | flowsToArgumentOfLikelyExternalLibraryCall ( arr ) |
171+ n = arr .getAnElement ( )
172+ )
173+ }
174+
175+ /**
176+ * Get calls for which we do not have the callee (i.e. the definition of the called function). This
177+ * acts as a heuristic for identifying calls to external library functions.
178+ */
179+ private DataFlow:: CallNode getACallWithoutCallee ( ) {
180+ forall ( Function callee | callee = result .getACallee ( ) | callee .getTopLevel ( ) .isExterns ( ) ) and
181+ not exists ( DataFlow:: ParameterNode param , DataFlow:: FunctionNode callback |
182+ param .flowsTo ( result .getCalleeNode ( ) ) and
183+ callback = getACallback ( param , DataFlow:: TypeBackTracker:: end ( ) )
184+ )
185+ }
186+
187+ /**
188+ * Gets a node that flows to callback-parameter `p`.
189+ */
190+ private DataFlow:: SourceNode getACallback ( DataFlow:: ParameterNode p , DataFlow:: TypeBackTracker t ) {
191+ t .start ( ) and
192+ result = p and
193+ any ( DataFlow:: FunctionNode f ) .getLastParameter ( ) = p and
194+ exists ( p .getACall ( ) )
195+ or
196+ exists ( DataFlow:: TypeBackTracker t2 | result = getACallback ( p , t2 ) .backtrack ( t2 , t ) )
197+ }
198+
199+ /**
200+ * Get calls which are likely to be to external non-built-in libraries.
201+ */
202+ DataFlow:: CallNode getALikelyExternalLibraryCall ( ) { result = getACallWithoutCallee ( ) }
203+
158204/*
159205 * Characteristics that are indicative of a sink.
160206 * NOTE: Initially each sink type has only one characteristic, which is that it's a sink of this type in the standard
@@ -582,7 +628,6 @@ abstract class EndpointFilterCharacteristic extends EndpointCharacteristic {
582628
583629/**
584630 * An EndpointFilterCharacteristic that indicates that an endpoint is unlikely to be a sink of any type.
585- * Replaces https://github.com/github/codeql/blob/387e57546bf7352f7c1cfe781daa1a3799b7063e/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/StandardEndpointFilters.qll#LL15C24-L15C24
586631 */
587632abstract private class StandardEndpointFilterCharacteristic extends EndpointFilterCharacteristic {
588633 bindingset [ this ]
@@ -786,7 +831,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh
786831 //
787832 // ## Direct arguments to external library calls
788833 //
789- // The `StandardEndpointFilters:: flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter
834+ // The `flowsToArgumentOfLikelyExternalLibraryCall` endpoint filter
790835 // allows sink candidates which are within object literals or array literals, for example
791836 // `req.sendFile(_, { path: ENDPOINT })`.
792837 //
@@ -809,7 +854,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkNosqlCh
809854 // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`.
810855 // We can't reuse the class because importing that file would cause us to treat these
811856 // heuristic sinks as known sinks.
812- not n = StandardEndpointFilters :: getALikelyExternalLibraryCall ( ) .getAnArgument ( ) and
857+ not n = getALikelyExternalLibraryCall ( ) .getAnArgument ( ) and
813858 not (
814859 SyntacticHeuristics:: isAssignedToOrConcatenatedWith ( n , "(?i)(nosql|query)" ) or
815860 SyntacticHeuristics:: isArgTo ( n , "(?i)(query)" )
@@ -878,7 +923,7 @@ private class NotAnArgumentToLikelyExternalLibraryCallOrHeuristicSinkCharacteris
878923 // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`.
879924 // We can't reuse the class because importing that file would cause us to treat these
880925 // heuristic sinks as known sinks.
881- not StandardEndpointFilters :: flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
926+ not flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
882927 not (
883928 SyntacticHeuristics:: isAssignedToOrConcatenatedWith ( n , "(?i)(sql|query)" ) or
884929 SyntacticHeuristics:: isArgTo ( n , "(?i)(query)" ) or
@@ -916,7 +961,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkTainted
916961 // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`.
917962 // We can't reuse the class because importing that file would cause us to treat these
918963 // heuristic sinks as known sinks.
919- not StandardEndpointFilters :: flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
964+ not flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
920965 not (
921966 SyntacticHeuristics:: isAssignedToOrConcatenatedWith ( n , "(?i)(file|folder|dir|absolute)" )
922967 or
@@ -977,7 +1022,7 @@ private class NotDirectArgumentToLikelyExternalLibraryCallOrHeuristicSinkXssChar
9771022 // `codeql/javascript/ql/src/semmle/javascript/heuristics/AdditionalSinks.qll`.
9781023 // We can't reuse the class because importing that file would cause us to treat these
9791024 // heuristic sinks as known sinks.
980- not StandardEndpointFilters :: flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
1025+ not flowsToArgumentOfLikelyExternalLibraryCall ( n ) and
9811026 not (
9821027 SyntacticHeuristics:: isAssignedToOrConcatenatedWith ( n , "(?i)(html|innerhtml)" )
9831028 or
0 commit comments