Improve intermediate flow to add more potential sources

This commit is contained in:
Tony Torralba
2021-08-23 11:57:12 +02:00
parent 28369d1822
commit 2ab7a55545
3 changed files with 131 additions and 13 deletions

View File

@@ -70,7 +70,8 @@ private class DefaultIntentRedirectionSanitizer extends IntentRedirectionSanitiz
DefaultIntentRedirectionSanitizer() {
exists(MethodAccess ma, Method m |
ma.getMethod() = m and
m.hasQualifiedName("android.content", "ComponentName", ["getPackageName", "getClassName"]) and
m.getDeclaringType() instanceof TypeComponentName and
m.hasName(["getPackageName", "getClassName"]) and
ma.getBasicBlock().(ConditionBlock).controls(this.asExpr().getBasicBlock(), true)
)
}

View File

@@ -3,10 +3,11 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.TaintTracking2
import semmle.code.java.security.AndroidIntentRedirection
/**
* A taint tracking configuration for user-provided Intents being used to start Android components.
* A taint tracking configuration for tainted Intents being used to start Android components.
*/
class IntentRedirectionConfiguration extends TaintTracking::Configuration {
IntentRedirectionConfiguration() { this = "IntentRedirectionConfiguration" }
@@ -24,30 +25,34 @@ class IntentRedirectionConfiguration extends TaintTracking::Configuration {
}
}
/** The method `getParcelableExtra` called on a tainted `Intent`. */
/** An expression modifying an `Intent` component with tainted data. */
private class IntentRedirectionSource extends DataFlow::Node {
IntentRedirectionSource() {
exists(GetParcelableExtra ma | this.asExpr() = ma.getQualifier()) and
exists(IntentToGetParcelableExtraConf conf | conf.hasFlowTo(this))
changesIntentComponent(this.asExpr()) and
exists(TaintedIntentComponentConf conf | conf.hasFlowTo(this))
}
}
/**
* Data flow from a remote intent to the qualifier of a `getParcelableExtra` call.
* A taint tracking configuration for tainted data flowing to an `Intent`'s component.
*/
private class IntentToGetParcelableExtraConf extends DataFlow2::Configuration {
IntentToGetParcelableExtraConf() { this = "IntentToGetParcelableExtraConf" }
private class TaintedIntentComponentConf extends TaintTracking2::Configuration {
TaintedIntentComponentConf() { this = "TaintedIntentComponentConf" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
exists(GetParcelableExtra ma | sink.asExpr() = ma.getQualifier())
}
override predicate isSink(DataFlow::Node sink) { changesIntentComponent(sink.asExpr()) }
}
/** Holds if `expr` modifies the component of an `Intent`. */
private predicate changesIntentComponent(Expr expr) {
any(IntentGetParcelableExtra igpe).getQualifier() = expr or
any(IntentSetComponent isc).getSink() = expr
}
/** A call to the method `Intent.getParcelableExtra`. */
private class GetParcelableExtra extends MethodAccess {
GetParcelableExtra() {
private class IntentGetParcelableExtra extends MethodAccess {
IntentGetParcelableExtra() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType() instanceof TypeIntent and
@@ -55,3 +60,33 @@ private class GetParcelableExtra extends MethodAccess {
)
}
}
/** A call to a method that changes the component of an `Intent`. */
private class IntentSetComponent extends MethodAccess {
int sinkArg;
IntentSetComponent() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType() instanceof TypeIntent
|
m.hasName("setClass") and
sinkArg = 1
or
m.hasName("setClassName") and
exists(Parameter p |
p = m.getAParameter() and
p.getType() instanceof TypeString and
sinkArg = p.getPosition()
)
or
m.hasName("setComponent") and
sinkArg = 0
or
m.hasName("setPackage") and
sinkArg = 0
)
}
Expr getSink() { result = this.getArgument(sinkArg) }
}

View File

@@ -1,6 +1,7 @@
package com.example.app;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -54,5 +55,86 @@ public class AndroidIntentRedirectionTest extends Activity {
sendStickyOrderedBroadcast(intent, null, null, 0, null, null); // $ hasAndroidIntentRedirection
sendStickyOrderedBroadcastAsUser(intent, null, null, null, 0, null, null); // $ hasAndroidIntentRedirection
// @formatter:on
try {
{
Intent fwdIntent = new Intent();
fwdIntent.setClassName((Context) null, (String) intent.getExtra("className"));
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
fwdIntent.setClassName((String) intent.getExtra("packageName"), null);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
fwdIntent.setClassName((String) intent.getExtra("packageName"),
(String) intent.getExtra("className"));
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
fwdIntent.setClass(null, Class.forName((String) intent.getExtra("className")));
// needs taint step for Class.forName
startActivity(fwdIntent); // $ MISSING: $hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
fwdIntent.setPackage((String) intent.getExtra("packageName"));
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component =
new ComponentName((String) intent.getExtra("packageName"), null);
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component =
new ComponentName("", (String) intent.getExtra("className"));
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component =
new ComponentName((Context) null, (String) intent.getExtra("className"));
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component = new ComponentName((Context) null,
Class.forName((String) intent.getExtra("className")));
fwdIntent.setComponent(component);
// needs taint step for Class.forName
startActivity(fwdIntent); // $ MISSING: $hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component =
ComponentName.createRelative("", (String) intent.getExtra("className"));
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component =
ComponentName.createRelative((String) intent.getExtra("packageName"), "");
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
{
Intent fwdIntent = new Intent();
ComponentName component = ComponentName.createRelative((Context) null,
(String) intent.getExtra("className"));
fwdIntent.setComponent(component);
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
}
} catch (Exception e) {
}
}
}