@@ -658,3 +658,49 @@ private predicate entrypointFieldStep(DataFlow::Node src, DataFlow::Node sink) {
658
658
) and
659
659
src .getType ( ) .( RefType ) .getSourceDeclaration ( ) = entrypointType ( )
660
660
}
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