mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge pull request #4512 from luchua-bc/sensitive-broadcast
Java: Sensitive broadcast
This commit is contained in:
@@ -9,21 +9,21 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import DataFlow
|
||||
import PathGraph
|
||||
|
||||
/**
|
||||
* Gets a regular expression for matching names of variables that indicate the value being held is a credential
|
||||
* Gets a regular expression for matching names of variables that indicate the value being held may contain sensitive information
|
||||
*/
|
||||
private string getACredentialRegex() {
|
||||
result = "(?i).*challenge|pass(wd|word|code|phrase)(?!.*question).*" or
|
||||
result = "(?i)(.*username|.*secret|url).*"
|
||||
}
|
||||
private string getACredentialRegex() { result = "(?i)(.*username|url).*" }
|
||||
|
||||
/** Variable keeps sensitive information judging by its name * */
|
||||
class CredentialExpr extends Expr {
|
||||
CredentialExpr() {
|
||||
exists(Variable v | this = v.getAnAccess() | v.getName().regexpMatch(getACredentialRegex()))
|
||||
exists(Variable v | this = v.getAnAccess() |
|
||||
v.getName().regexpMatch([getCommonSensitiveInfoRegex(), getACredentialRegex()])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
public void sendBroadcast1(Context context, String token, String refreshToken)
|
||||
{
|
||||
{
|
||||
// BAD: broadcast sensitive information to all listeners
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("token", token);
|
||||
intent.putExtra("refreshToken", refreshToken);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: broadcast sensitive information only to those with permission
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("token", token);
|
||||
intent.putExtra("refreshToken", refreshToken);
|
||||
context.sendBroadcast(intent, "com.example.user_permission");
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: broadcast sensitive information to a specific application
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.setClassName("com.example2", "com.example2.UserInfoHandler");
|
||||
intent.putExtra("token", token);
|
||||
intent.putExtra("refreshToken", refreshToken);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Broadcast intents in an Android application are visible to all applications installed on the same mobile device, exposing all sensitive information they contain.</p>
|
||||
<p>Broadcasts are vulnerable to passive eavesdropping or active denial of service attacks when an intent is broadcast without specifying any receiver permission or receiver application.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Specify a receiver permission or application when broadcasting intents, or switch to
|
||||
<code>LocalBroadcastManager</code>
|
||||
or the latest
|
||||
<code>LiveData</code>
|
||||
library.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example shows two ways of broadcasting intents. In the 'BAD' case, no "receiver permission" is specified. In the 'GOOD' case, "receiver permission" or "receiver application" is specified.</p>
|
||||
<sample src="SensitiveBroadcast.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
CWE:
|
||||
<a href="https://cwe.mitre.org/data/definitions/927.html">CWE-927: Use of Implicit Intent for Sensitive Communication</a>
|
||||
</li>
|
||||
<li>
|
||||
Android Developers:
|
||||
<a href="https://developer.android.com/guide/components/broadcasts">Security considerations and best practices for sending and receiving broadcasts</a>
|
||||
</li>
|
||||
<li>
|
||||
SonarSource:
|
||||
<a href="https://rules.sonarsource.com/java/type/Security%20Hotspot/RSPEC-5320">Broadcasting intents is security-sensitive</a>
|
||||
</li>
|
||||
<li>
|
||||
Android Developer Fundamentals:
|
||||
<a href="https://google-developer-training.github.io/android-developer-fundamentals-course-concepts-v2/unit-3-working-in-the-background/lesson-7-background-tasks/7-3-c-broadcasts/7-3-c-broadcasts.html">Restricting broadcasts</a>
|
||||
</li>
|
||||
<li>
|
||||
Carnegie Mellon University:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/android/DRD03-J.+Do+not+broadcast+sensitive+information+using+an+implicit+intent">DRD03-J. Do not broadcast sensitive information using an implicit intent</a>
|
||||
</li>
|
||||
<li>
|
||||
Android Developers:
|
||||
<a href="https://developer.android.com/topic/libraries/architecture/livedata">Android LiveData Overview</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @name Broadcasting sensitive data to all Android applications
|
||||
* @id java/sensitive-broadcast
|
||||
* @description An Android application uses implicit intents to broadcast sensitive data to all applications without specifying any receiver permission.
|
||||
* @kind path-problem
|
||||
* @tags security
|
||||
* external/cwe-927
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow3
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.frameworks.android.Intent
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Gets regular expression for matching names of Android variables that indicate the value being held contains sensitive information.
|
||||
*/
|
||||
private string getAndroidSensitiveInfoRegex() { result = "(?i).*(email|phone|ticket).*" }
|
||||
|
||||
/**
|
||||
* Method call to pass information to the `Intent` object.
|
||||
*/
|
||||
class PutIntentExtraMethodAccess extends MethodAccess {
|
||||
PutIntentExtraMethodAccess() {
|
||||
(
|
||||
getMethod().getName().matches("put%Extra") or
|
||||
getMethod().hasName("putExtras")
|
||||
) and
|
||||
getMethod().getDeclaringType() instanceof TypeIntent
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method call to pass information to the intent extra bundle object.
|
||||
*/
|
||||
class PutBundleExtraMethodAccess extends MethodAccess {
|
||||
PutBundleExtraMethodAccess() {
|
||||
getMethod().getName().regexpMatch("put\\w+") and
|
||||
getMethod().getDeclaringType().getASupertype*().hasQualifiedName("android.os", "BaseBundle")
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds variables that hold sensitive information judging by their names. */
|
||||
class SensitiveInfoExpr extends Expr {
|
||||
SensitiveInfoExpr() {
|
||||
exists(Variable v | this = v.getAnAccess() |
|
||||
v.getName().regexpMatch([getCommonSensitiveInfoRegex(), getAndroidSensitiveInfoRegex()])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method access of the `Context.sendBroadcast` family.
|
||||
*/
|
||||
class SendBroadcastMethodAccess extends MethodAccess {
|
||||
SendBroadcastMethodAccess() {
|
||||
this.getMethod().getDeclaringType() instanceof TypeContext and
|
||||
this.getMethod().getName().matches("send%Broadcast%")
|
||||
}
|
||||
}
|
||||
|
||||
private class NullArgFlowConfig extends DataFlow2::Configuration {
|
||||
NullArgFlowConfig() { this = "Flow configuration with a null argument" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof NullLiteral }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(SendBroadcastMethodAccess ma | sink.asExpr() = ma.getAnArgument())
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyArrayArgFlowConfig extends DataFlow3::Configuration {
|
||||
EmptyArrayArgFlowConfig() { this = "Flow configuration with an empty array argument" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr().(ArrayCreationExpr).getFirstDimensionSize() = 0
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(SendBroadcastMethodAccess ma | sink.asExpr() = ma.getAnArgument())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a `sendBroadcast` call doesn't specify receiver permission.
|
||||
*/
|
||||
predicate isSensitiveBroadcastSink(DataFlow::Node sink) {
|
||||
exists(SendBroadcastMethodAccess ma |
|
||||
sink.asExpr() = ma.getAnArgument() and
|
||||
(
|
||||
ma.getMethod().hasName("sendBroadcast") and
|
||||
(
|
||||
ma.getNumArgument() = 1 // sendBroadcast(Intent intent)
|
||||
or
|
||||
// sendBroadcast(Intent intent, String receiverPermission)
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(1))))
|
||||
)
|
||||
or
|
||||
ma.getMethod().hasName("sendBroadcastAsUser") and
|
||||
(
|
||||
ma.getNumArgument() = 2 or // sendBroadcastAsUser(Intent intent, UserHandle user)
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(2)))) // sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)
|
||||
)
|
||||
or
|
||||
ma.getMethod().hasName("sendBroadcastWithMultiplePermissions") and
|
||||
exists(EmptyArrayArgFlowConfig config |
|
||||
config.hasFlow(_, DataFlow::exprNode(ma.getArgument(1))) // sendBroadcastWithMultiplePermissions(Intent intent, String[] receiverPermissions)
|
||||
)
|
||||
or
|
||||
// Method calls of `sendOrderedBroadcast` whose second argument is always `receiverPermission`
|
||||
ma.getMethod().hasName("sendOrderedBroadcast") and
|
||||
(
|
||||
// sendOrderedBroadcast(Intent intent, String receiverPermission) or sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(1)))) and
|
||||
ma.getNumArgument() <= 7
|
||||
or
|
||||
// sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(1)))) and
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(2)))) and
|
||||
ma.getNumArgument() = 8
|
||||
)
|
||||
or
|
||||
// Method call of `sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)`
|
||||
ma.getMethod().hasName("sendOrderedBroadcastAsUser") and
|
||||
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(2))))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint configuration tracking flow from variables containing sensitive information to broadcast intents.
|
||||
*/
|
||||
class SensitiveBroadcastConfig extends TaintTracking::Configuration {
|
||||
SensitiveBroadcastConfig() { this = "Sensitive Broadcast Configuration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof SensitiveInfoExpr
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { isSensitiveBroadcastSink(sink) }
|
||||
|
||||
/**
|
||||
* Holds if there is an additional flow step from `PutIntentExtraMethodAccess` or `PutBundleExtraMethodAccess` that taints the `Intent` or its extras `Bundle`.
|
||||
*/
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(PutIntentExtraMethodAccess pia |
|
||||
node1.asExpr() = pia.getAnArgument() and node2.asExpr() = pia.getQualifier()
|
||||
)
|
||||
or
|
||||
exists(PutBundleExtraMethodAccess pba |
|
||||
node1.asExpr() = pba.getAnArgument() and node2.asExpr() = pba.getQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if broadcast doesn't specify receiving package name of the 3rd party app
|
||||
*/
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
exists(MethodAccess setReceiverMa |
|
||||
setReceiverMa.getMethod().hasName(["setPackage", "setClass", "setClassName", "setComponent"]) and
|
||||
setReceiverMa.getQualifier().(VarAccess).getVariable().getAnAccess() = node.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from SensitiveBroadcastConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Sending $@ to broadcast.", source.getNode(),
|
||||
"sensitive information"
|
||||
@@ -27,6 +27,14 @@ private string nonSuspicious() {
|
||||
result = "%crypt%"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a regular expression for matching common names of variables that indicate the value being held contains sensitive information.
|
||||
*/
|
||||
string getCommonSensitiveInfoRegex() {
|
||||
result = "(?i).*challenge|pass(wd|word|code|phrase)(?!.*question).*" or
|
||||
result = "(?i).*(token|secret).*"
|
||||
}
|
||||
|
||||
/** An expression that might contain sensitive data. */
|
||||
abstract class SensitiveExpr extends Expr { }
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
edges
|
||||
| SensitiveBroadcast.java:12:34:12:38 | token : String | SensitiveBroadcast.java:14:31:14:36 | intent |
|
||||
| SensitiveBroadcast.java:13:41:13:52 | refreshToken : String | SensitiveBroadcast.java:14:31:14:36 | intent |
|
||||
| SensitiveBroadcast.java:25:32:25:39 | password : String | SensitiveBroadcast.java:26:31:26:36 | intent |
|
||||
| SensitiveBroadcast.java:36:35:36:39 | email : String | SensitiveBroadcast.java:38:31:38:36 | intent |
|
||||
| SensitiveBroadcast.java:50:22:50:29 | password : String | SensitiveBroadcast.java:52:31:52:36 | intent |
|
||||
| SensitiveBroadcast.java:97:35:97:40 | ticket : String | SensitiveBroadcast.java:98:54:98:59 | intent |
|
||||
| SensitiveBroadcast.java:109:32:109:39 | passcode : String | SensitiveBroadcast.java:111:54:111:59 | intent |
|
||||
| SensitiveBroadcast.java:136:33:136:38 | passwd : String | SensitiveBroadcast.java:140:54:140:59 | intent |
|
||||
nodes
|
||||
| SensitiveBroadcast.java:12:34:12:38 | token : String | semmle.label | token : String |
|
||||
| SensitiveBroadcast.java:13:41:13:52 | refreshToken : String | semmle.label | refreshToken : String |
|
||||
| SensitiveBroadcast.java:14:31:14:36 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:25:32:25:39 | password : String | semmle.label | password : String |
|
||||
| SensitiveBroadcast.java:26:31:26:36 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:36:35:36:39 | email : String | semmle.label | email : String |
|
||||
| SensitiveBroadcast.java:38:31:38:36 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:50:22:50:29 | password : String | semmle.label | password : String |
|
||||
| SensitiveBroadcast.java:52:31:52:36 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:97:35:97:40 | ticket : String | semmle.label | ticket : String |
|
||||
| SensitiveBroadcast.java:98:54:98:59 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:109:32:109:39 | passcode : String | semmle.label | passcode : String |
|
||||
| SensitiveBroadcast.java:111:54:111:59 | intent | semmle.label | intent |
|
||||
| SensitiveBroadcast.java:136:33:136:38 | passwd : String | semmle.label | passwd : String |
|
||||
| SensitiveBroadcast.java:140:54:140:59 | intent | semmle.label | intent |
|
||||
#select
|
||||
| SensitiveBroadcast.java:14:31:14:36 | intent | SensitiveBroadcast.java:12:34:12:38 | token : String | SensitiveBroadcast.java:14:31:14:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:12:34:12:38 | token | sensitive information |
|
||||
| SensitiveBroadcast.java:14:31:14:36 | intent | SensitiveBroadcast.java:13:41:13:52 | refreshToken : String | SensitiveBroadcast.java:14:31:14:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:13:41:13:52 | refreshToken | sensitive information |
|
||||
| SensitiveBroadcast.java:26:31:26:36 | intent | SensitiveBroadcast.java:25:32:25:39 | password : String | SensitiveBroadcast.java:26:31:26:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:25:32:25:39 | password | sensitive information |
|
||||
| SensitiveBroadcast.java:38:31:38:36 | intent | SensitiveBroadcast.java:36:35:36:39 | email : String | SensitiveBroadcast.java:38:31:38:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:36:35:36:39 | email | sensitive information |
|
||||
| SensitiveBroadcast.java:52:31:52:36 | intent | SensitiveBroadcast.java:50:22:50:29 | password : String | SensitiveBroadcast.java:52:31:52:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:50:22:50:29 | password | sensitive information |
|
||||
| SensitiveBroadcast.java:98:54:98:59 | intent | SensitiveBroadcast.java:97:35:97:40 | ticket : String | SensitiveBroadcast.java:98:54:98:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:97:35:97:40 | ticket | sensitive information |
|
||||
| SensitiveBroadcast.java:111:54:111:59 | intent | SensitiveBroadcast.java:109:32:109:39 | passcode : String | SensitiveBroadcast.java:111:54:111:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:109:32:109:39 | passcode | sensitive information |
|
||||
| SensitiveBroadcast.java:140:54:140:59 | intent | SensitiveBroadcast.java:136:33:136:38 | passwd : String | SensitiveBroadcast.java:140:54:140:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:136:33:136:38 | passwd | sensitive information |
|
||||
@@ -0,0 +1,173 @@
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class SensitiveBroadcast {
|
||||
|
||||
// BAD - Tests broadcast of access token with intent extra.
|
||||
public void sendBroadcast1(Context context, String token, String refreshToken) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("token", token);
|
||||
intent.putExtra("refreshToken", refreshToken);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with intent extra.
|
||||
public void sendBroadcast2(Context context) {
|
||||
String userName = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", userName);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of email information with extra bundle.
|
||||
public void sendBroadcast3(Context context) {
|
||||
String email = "user123@example.com";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("email", email);
|
||||
intent.putExtras(bundle);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with null permission.
|
||||
public void sendBroadcast4(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
ArrayList<String> userinfo = new ArrayList<String>();
|
||||
userinfo.add(username);
|
||||
userinfo.add(password);
|
||||
intent.putStringArrayListExtra("userinfo", userinfo);
|
||||
context.sendBroadcast(intent, null);
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with permission using string literal.
|
||||
public void sendBroadcast5(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendBroadcast(intent, "com.example.user_permission");
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of access ticket with permission using string object.
|
||||
public void sendBroadcast6(Context context) {
|
||||
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("ticket", ticket);
|
||||
String perm = "com.example.user_permission";
|
||||
context.sendBroadcast(intent, perm);
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information to a specific application.
|
||||
public void sendBroadcast7(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.setClassName("com.example2", "com.example2.UserInfoHandler");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of access ticket with multiple permissions using direct empty array initialization.
|
||||
public void sendBroadcast8(Context context) {
|
||||
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("ticket", ticket);
|
||||
context.sendBroadcastWithMultiplePermissions(intent, new String[]{});
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through a variable.
|
||||
public void sendBroadcast9(Context context) {
|
||||
String username = "test123";
|
||||
String passcode = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", passcode);
|
||||
String[] perms = new String[0];
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms);
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with multiple permissions.
|
||||
public void sendBroadcast10(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
String[] perms = new String[]{"com.example.custom_action", "com.example.custom_action2"};
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms);
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables and `intent.putExtras(bundle)`.
|
||||
public void sendBroadcast11(Context context) {
|
||||
String username = "test123";
|
||||
String passwd = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("name", username);
|
||||
bundle.putString("pwd", passwd);
|
||||
intent.putExtras(bundle);
|
||||
String[] perms = new String[0];
|
||||
String[] perms2 = perms;
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2);
|
||||
}
|
||||
|
||||
/**
|
||||
* BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables and `intent.getExtras().putString()`.
|
||||
* Note this case of `getExtras().putString(...)` is not yet detected thus is beyond what the query is capable of.
|
||||
*/
|
||||
public void sendBroadcast12(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
intent.putExtras(bundle);
|
||||
intent.getExtras().putString("name", username);
|
||||
intent.getExtras().putString("pwd", password);
|
||||
String[] perms = new String[0];
|
||||
String[] perms2 = perms;
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2);
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with ordered broadcast.
|
||||
public void sendBroadcast13(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendOrderedBroadcast(intent, "com.example.USER_PERM");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-927/SensitiveBroadcast.ql
|
||||
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0
|
||||
Reference in New Issue
Block a user