@@ -658,3 +658,49 @@ private predicate entrypointFieldStep(DataFlow::Node src, DataFlow::Node sink) {
658658 ) and
659659 src .getType ( ) .( RefType ) .getSourceDeclaration ( ) = entrypointType ( )
660660}
661+
662+ import SpeculativeTaintFlow
663+
664+ private module SpeculativeTaintFlow {
665+ private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow
666+ private import semmle.code.java.dataflow.internal.DataFlowNodes
667+ private import semmle.code.java.dataflow.internal.FlowSummaryImpl as Impl
668+ private import semmle.code.java.dispatch.VirtualDispatch
669+ private import semmle.code.java.security.Sanitizers
670+
671+ private predicate hasTarget ( Call call ) {
672+ exists ( Impl:: Public:: SummarizedCallable sc | sc .getACall ( ) = call )
673+ or
674+ exists ( Impl:: Public:: NeutralSummaryCallable nc | nc .getACall ( ) = call )
675+ or
676+ call .getCallee ( ) .getSourceDeclaration ( ) instanceof ExternalFlow:: SinkCallable
677+ or
678+ exists ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .getACall ( ) = call )
679+ or
680+ exists ( viableCallable ( call ) )
681+ or
682+ call .getQualifier ( ) .getType ( ) instanceof Array
683+ or
684+ call .getCallee ( ) .getSourceDeclaration ( ) instanceof CloneMethod
685+ or
686+ call .getCallee ( )
687+ .getSourceDeclaration ( )
688+ .getDeclaringType ( )
689+ .getPackage ( )
690+ .hasName ( "java.util.function" )
691+ }
692+
693+ predicate speculativeTaintStep ( DataFlow:: Node src , DataFlow:: Node sink ) {
694+ exists ( DataFlowCall call , Call srcCall , int argpos |
695+ not hasTarget ( srcCall ) and
696+ call .asCall ( ) = srcCall and
697+ src .( ArgumentNode ) .argumentOf ( call , argpos ) and
698+ not src instanceof SimpleTypeSanitizer
699+ |
700+ argpos != - 1 and
701+ sink .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) = Public:: getInstanceArgument ( srcCall )
702+ or
703+ sink .( OutNode ) .getCall ( ) = call
704+ )
705+ }
706+ }
0 commit comments