Java: Add support for speculative taint flow.

This commit is contained in:
Anders Schack-Mulligen
2024-09-24 13:48:41 +02:00
parent 7d123296f8
commit 8b99154a00

View File

@@ -658,3 +658,49 @@ private predicate entrypointFieldStep(DataFlow::Node src, DataFlow::Node sink) {
) and
src.getType().(RefType).getSourceDeclaration() = entrypointType()
}
import SpeculativeTaintFlow
private module SpeculativeTaintFlow {
private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow
private import semmle.code.java.dataflow.internal.DataFlowNodes
private import semmle.code.java.dataflow.internal.FlowSummaryImpl as Impl
private import semmle.code.java.dispatch.VirtualDispatch
private import semmle.code.java.security.Sanitizers
private predicate hasTarget(Call call) {
exists(Impl::Public::SummarizedCallable sc | sc.getACall() = call)
or
exists(Impl::Public::NeutralSummaryCallable nc | nc.getACall() = call)
or
call.getCallee().getSourceDeclaration() instanceof ExternalFlow::SinkCallable
or
exists(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.getACall() = call)
or
exists(viableCallable(call))
or
call.getQualifier().getType() instanceof Array
or
call.getCallee().getSourceDeclaration() instanceof CloneMethod
or
call.getCallee()
.getSourceDeclaration()
.getDeclaringType()
.getPackage()
.hasName("java.util.function")
}
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) {
exists(DataFlowCall call, Call srcCall, int argpos |
not hasTarget(srcCall) and
call.asCall() = srcCall and
src.(ArgumentNode).argumentOf(call, argpos) and
not src instanceof SimpleTypeSanitizer
|
argpos != -1 and
sink.(DataFlow::PostUpdateNode).getPreUpdateNode() = Public::getInstanceArgument(srcCall)
or
sink.(OutNode).getCall() = call
)
}
}