Added query ImplicitPendingIntents

This commit is contained in:
Tony Torralba
2021-09-30 11:28:39 +02:00
parent 68385dfab5
commit d0077b8c12
8 changed files with 405 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
public class ImplicitPendingIntents extends Activity {
public void onCreate(Bundle savedInstance) {
{
// BAD: an implicit Intent is used to create a PendingIntent.
// The PendingIntent is then added to another implicit Intent
// and started.
Intent baseIntent = new Intent();
PendingIntent pi =
PendingIntent.getActivity(this, 0, baseIntent, PendingIntent.FLAG_ONE_SHOT);
Intent fwdIntent = new Intent("SOME_ACTION");
fwdIntent.putExtra("fwdIntent", pi);
sendBroadcast(fwdIntent);
}
{
// GOOD: both the PendingIntent and the wrapping Intent are explicit.
Intent safeIntent = new Intent(this, AnotherActivity.class);
PendingIntent pi =
PendingIntent.getActivity(this, 0, safeIntent, PendingIntent.FLAG_ONE_SHOT);
Intent fwdIntent = new Intent();
fwdIntent.setClassName("destination.package", "DestinationClass");
fwdIntent.putExtra("fwdIntent", pi);
startActivity(fwdIntent);
}
{
// GOOD: The PendingIntent is created with FLAG_IMMUTABLE.
Intent baseIntent = new Intent("SOME_ACTION");
PendingIntent pi =
PendingIntent.getActivity(this, 0, baseIntent, PendingIntent.FLAG_IMMUTABLE);
Intent fwdIntent = new Intent();
fwdIntent.setClassName("destination.package", "DestinationClass");
fwdIntent.putExtra("fwdIntent", pi);
startActivity(fwdIntent);
}
}
}

View File

@@ -0,0 +1,58 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>A <code>PendingIntent</code> describes an action in the form of an Intent that is intended to be given and executed
at a later time by another application. The Intent wrapped by a <code>PendingIntent</code> is executed on behalf of
the application that created it, and with its same privileges.</p>
<p>If a <code>PendingIntent</code> is configured to be mutable, the fields of its internal Intent can be changed by the
receiving application if they were not previously set. This means that a mutable <code>PendingIntent</code> that has
not defined a destination component (that is, an implicit <code>PendingIntent</code>) can be directed to any component
by the receiving application, and execute an arbitrary action with the privileges of the application that created it.</p>
<p>If an implicit <code>PendingIntent</code> is wrapped and sent as an extra of an Intent that can be intercepted (that
is, again, an implicit Intent), any malicious application could obtain the <code>PendingIntent</code>, modify the
underlying Intent with an arbitrary destination component, and execute the desired action with elevated privileges.
This could give the malicious application access to private components of the victim application, or the ability to
perform actions without having the necessary permissions.</p>
</overview>
<recommendation>
<p>Avoid creating implicit <code>PendingIntent</code>s. This means that the underlying Intent should always have an
explicit destination component.</p>
<p>Also, when adding the <code>PendingIntent</code> as an extra of another Intent, make sure that said Intent also has
an explicit destination component, so that it is not delivered to untrusted applications.</p>
<p>It is also recommended to create the <code>PendingIntent</code> using the flag <code>FLAG_IMMUTABLE</code> whenever
possible, to prevent the destination component from modifying empty fields of the underlying Intent.</p>
</recommendation>
<example>
<p>In the following examples, a <code>PendingIntent</code> is created and wrapped as an extra of another Intent.
</p>
<p>In the first example, both the <code>PendingIntent</code> and the Intent it is wrapped in are implicit,
reproducing the vulnerability.</p>
<p>In the second example, the issue is avoided by adding explicit destination components to the
<code>PendingIntent</code> and the wrapping Intent.</p>
<p>The third example uses the <code>FLAG_IMMUTABLE</code> flag to prevent the underlying Intent from being modified
by the destination component.</p>
<sample src="ImplicitPendingIntents.java" />
</example>
<references>
<li>
Google Help:
<a href="https://support.google.com/faqs/answer/10437428?hl=en">
Remediation for Implicit PendingIntent Vulnerability
</a>
</li>
<li>
University of Potsdam:
<a href="https://www.cs.uni-potsdam.de/se/papers/esorics18.pdf">
PIAnalyzer: A precise approach for PendingIntent vulnerability analysis
</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,22 @@
/**
* @name Use of implicit Pending Intents
* @description Implicit and mutable PendingIntents being wrapped and sent in another implicit
* Intent may provide access to internal components of the application or cause other
* unintended effects.
* @kind path-problem
* @problem.severity error
* @security-severity 8.2
* @precision high
* @id java/android/pending-intents
* @tags security
* external/cwe/cwe-927
*/
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.ImplicitPendingIntentsQuery
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink
where any(ImplicitPendingIntentStartConf conf).hasFlowPath(source, sink)
select sink.getNode(), source, sink, "something"

View File

@@ -0,0 +1,7 @@
---
category: newQuery
---
* A new query "Use of implicit Pending Intents" (`java/android/pending-intents`) has been added.
This query finds implicit and mutable PendingIntents being wrapped and sent in another implicit Intent,
which can provide access to internal components of the application or cause other unintended
effects.