mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Improve intermediate flow to add more potential sources
This commit is contained in:
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user