diff --git a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRAnalysisManager.kt b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRAnalysisManager.kt index cf928a62a..5b5724f72 100644 --- a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRAnalysisManager.kt +++ b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRAnalysisManager.kt @@ -66,7 +66,7 @@ class JIRAnalysisManager( data class Params( val aliasAnalysisParams: JIRLocalAliasAnalysis.Params = JIRLocalAliasAnalysis.Params(), - val disableDefaultGetModel: Boolean = false, + val defaultGetModel: JIRMethodGetDefault? = null, ) private val relevantRuleIds = ConcurrentHashMap.newKeySet() diff --git a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodCallFlowFunction.kt b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodCallFlowFunction.kt index 5ee1493f3..aa590a7af 100644 --- a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodCallFlowFunction.kt +++ b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodCallFlowFunction.kt @@ -279,6 +279,9 @@ class JIRMethodCallFlowFunction( apManager, analysisContext.factTypeChecker, passFactReader, typeResolver ) + val passRules = taintCtx.passRulesForCallStatement(statement, callExpr, returnValue, passFactReader.factAp) + var passThroughFacts = applyPassThrough(passRules, conditionEvaluator, passEvaluator) + if (startFactBase !is AccessPathBase.ClassStatic) { analysisContext.taint.externalMethodTracker?.let { tracker -> if (JIRCallResolver.alwaysIgnoreMethod(method)) return@let @@ -291,11 +294,9 @@ class JIRMethodCallFlowFunction( } } - val passRules = taintCtx.passRulesForCallStatement(statement, callExpr, returnValue, passFactReader.factAp) - var passThroughFacts = applyPassThrough(passRules, conditionEvaluator, passEvaluator) - - if (/*todo: fix owasp passThroughFacts.isNone && */!analysisContext.analysisManager.params.disableDefaultGetModel) { - val defaultRules = JIRMethodGetDefault.defaultPropagationRules(method) + analysisContext.analysisManager.params.defaultGetModel?.run { + /*todo: fix owasp, propagate default only if passThroughFacts.isNone */ + val defaultRules = defaultPropagationRules(method) val defaultPass = applyPassThrough(defaultRules, conditionEvaluator, passEvaluator) passThroughFacts = passThroughFacts.merge(defaultPass) } diff --git a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodGetDefault.kt b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodGetDefault.kt index ba61d16a5..b98f0aff3 100644 --- a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodGetDefault.kt +++ b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/analysis/JIRMethodGetDefault.kt @@ -9,22 +9,38 @@ import org.opentaint.dataflow.configuration.jvm.TaintPassThrough import org.opentaint.dataflow.configuration.jvm.This import org.opentaint.dataflow.configuration.mkTrue import org.opentaint.dataflow.taint.RuleConditionRewriter +import org.opentaint.ir.api.jvm.JIRClassOrInterface import org.opentaint.ir.api.jvm.JIRMethod import org.opentaint.ir.api.jvm.TypeName import org.opentaint.ir.impl.cfg.util.isArray import org.opentaint.ir.impl.types.TypeNameImpl -object JIRMethodGetDefault { +class JIRMethodGetDefault( + private val config: Configuration, +) { + interface Configuration { + fun enableDefaultPropagationForClass(cls: JIRClassOrInterface): Boolean + } + private val objectTypeName = TypeNameImpl.fromTypeName("java.lang.Object") private fun TypeName.mayBeArray(): Boolean = isArray || this == objectTypeName - private val getDefaultActions = listOf( - CopyAllMarks(from = This, to = Result) + private fun defaultField(cls: JIRClassOrInterface): PositionAccessor.FieldAccessor = + PositionAccessor.FieldAccessor(cls.name, "", objectTypeName.typeName) + + private fun defaultPosition(cls: JIRClassOrInterface) = + PositionWithAccess(This, defaultField(cls)) + + private fun getDefaultActions(cls: JIRClassOrInterface) = listOf( + CopyAllMarks(from = defaultPosition(cls), to = Result) ) - private val getDefaultArrayActions = listOf( - CopyAllMarks(from = This, to = PositionWithAccess(Result, PositionAccessor.ElementAccessor)) + private fun getDefaultArrayActions(cls: JIRClassOrInterface) = listOf( + CopyAllMarks( + from = defaultPosition(cls), + to = PositionWithAccess(Result, PositionAccessor.ElementAccessor) + ) ) fun defaultPropagationRules(method: JIRMethod): List> { @@ -32,9 +48,11 @@ object JIRMethodGetDefault { if (!method.name.startsWith("get")) return emptyList() - var actions = getDefaultActions + if (!config.enableDefaultPropagationForClass(method.enclosingClass)) return emptyList() + + var actions = getDefaultActions(method.enclosingClass) if (method.returnType.mayBeArray()) { - actions = actions + getDefaultArrayActions + actions = actions + getDefaultArrayActions(method.enclosingClass) } val getDefaultRule = TaintPassThrough(method, mkTrue(), actions, info = null) diff --git a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/trace/JIRMethodCallPrecondition.kt b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/trace/JIRMethodCallPrecondition.kt index c9b0f53a0..21b3b1f05 100644 --- a/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/trace/JIRMethodCallPrecondition.kt +++ b/core/opentaint-dataflow-core/opentaint-jvm-dataflow/src/main/kotlin/org/opentaint/dataflow/jvm/ap/ifds/trace/JIRMethodCallPrecondition.kt @@ -19,7 +19,6 @@ import org.opentaint.dataflow.jvm.ap.ifds.JIRMethodCallFactMapper.factIsRelevant import org.opentaint.dataflow.jvm.ap.ifds.MethodFlowFunctionUtils import org.opentaint.dataflow.jvm.ap.ifds.TaintConfigUtils.accept import org.opentaint.dataflow.jvm.ap.ifds.analysis.JIRMethodAnalysisContext -import org.opentaint.dataflow.jvm.ap.ifds.analysis.JIRMethodGetDefault import org.opentaint.dataflow.jvm.ap.ifds.analysis.forEachPossibleAliasAtStatement import org.opentaint.dataflow.jvm.ap.ifds.taint.resolveAp import org.opentaint.dataflow.jvm.util.callee @@ -136,8 +135,9 @@ class JIRMethodCallPrecondition( ) { val passRules = taintCtx.passRulesForCallStatement(statement, callExpr, returnValue, fact = null).toMutableList() - if (!analysisContext.analysisManager.params.disableDefaultGetModel) { - passRules += JIRMethodGetDefault.defaultPropagationRules(callExpr.method.method) + + analysisContext.analysisManager.params.defaultGetModel?.run { + passRules += defaultPropagationRules(callExpr.method.method) } if (passRules.isEmpty()) return diff --git a/core/opentaint-jvm-sast-dataflow/src/main/kotlin/org/opentaint/jvm/sast/dataflow/JIRTaintAnalyzer.kt b/core/opentaint-jvm-sast-dataflow/src/main/kotlin/org/opentaint/jvm/sast/dataflow/JIRTaintAnalyzer.kt index a5ab016fc..9c4263732 100644 --- a/core/opentaint-jvm-sast-dataflow/src/main/kotlin/org/opentaint/jvm/sast/dataflow/JIRTaintAnalyzer.kt +++ b/core/opentaint-jvm-sast-dataflow/src/main/kotlin/org/opentaint/jvm/sast/dataflow/JIRTaintAnalyzer.kt @@ -12,6 +12,7 @@ import org.opentaint.dataflow.jvm.ap.ifds.JIRSummarySerializationContext import org.opentaint.dataflow.jvm.ap.ifds.LambdaAnonymousClassFeature import org.opentaint.dataflow.jvm.ap.ifds.LambdaAnonymousClassFeature.JIRLambdaMethod import org.opentaint.dataflow.jvm.ap.ifds.analysis.JIRAnalysisManager +import org.opentaint.dataflow.jvm.ap.ifds.analysis.JIRMethodGetDefault import org.opentaint.dataflow.jvm.ap.ifds.taint.TaintRulesProvider import org.opentaint.dataflow.jvm.ifds.JIRUnitResolver import org.opentaint.dataflow.jvm.ifds.PackageUnit @@ -47,12 +48,23 @@ class JIRTaintAnalyzer( ) private val analysisParams get() = JIRAnalysisManager.Params( - disableDefaultGetModel = jirOptions.disableDefaultGetModel, + defaultGetModel = configureDefaultModel(), aliasAnalysisParams = JIRLocalAliasAnalysis.Params( aliasAnalysisInterProcCallDepth = options.experimentalAAInterProcCallDepth ) ) + private fun configureDefaultModel(): JIRMethodGetDefault? { + if (jirOptions.disableDefaultGetModel) return null + + val config = object : JIRMethodGetDefault.Configuration { + override fun enableDefaultPropagationForClass(cls: JIRClassOrInterface): Boolean = + !projectClasses.isProjectClass(cls) + } + + return JIRMethodGetDefault(config) + } + private val taintConfig: TaintRulesProvider by lazy { StringConcatRuleProvider(taintConfiguration) }