mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +01:00
Added query ImplicitPendingIntents
This commit is contained in:
43
java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.java
Normal file
43
java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
22
java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql
Normal file
22
java/ql/src/Security/CWE/CWE-927/ImplicitPendingIntents.ql
Normal 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"
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user