-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Java: Promote android sensitive broadcast query #6599
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: Promote android sensitive broadcast query #6599
Conversation
javaGenerated file changes for java
- Android,``android.*``,18,34,70,,,3,67,,,
+ Android,``android.*``,18,136,70,,,3,67,,,
- Totals,,84,3495,398,13,6,6,107,33,1,66
+ Totals,,84,3597,398,13,6,6,107,33,1,66
- android.content,8,,4,,,,,,,,,,,,,8,,,,,,4,
+ android.content,8,,44,,,,,,,,,,,,,8,,,,,,4,40
+ android.os,,,62,,,,,,,,,,,,,,,,,,,,62 |
"android.os;Bundle;true;putSizeF;;;Argument[0];MapKey of Argument[-1];value", | ||
"android.os;Bundle;true;putSparseParcelableArray;;;Argument[1];MapValue of Argument[-1];value", | ||
"android.os;Bundle;true;putStringArrayList;;;Argument[1];MapValue of Argument[-1];value", | ||
"android.content;Intent;true;getExtras;();;SyntheticField[android.content.Intent.extras] of Argument[-1];ReturnValue;value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing fluent mutators: addCategory
, addFlags
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some inline comments. I still need to review the CSV models in detail.
java/ql/src/semmle/code/java/security/AndroidSensitiveBroadcastQuery.qll
Outdated
Show resolved
Hide resolved
java/ql/src/semmle/code/java/security/AndroidSensitiveBroadcastQuery.qll
Outdated
Show resolved
Hide resolved
@joefarebrother IMHO yes, it would make sense, because you can send implicit (and thus, interceptable) Intents with those methods, although the exploitation is a little harder because the user needs to select the malicious app in a dialog for the Intent to reach it. The query would need to identify implicit Intents (i.e. explicit component not set, just an action). I think some code from this PR could be reused for that. |
Do the existing sanitizers for |
Probably, now that you mention it. I was thinking that we could reuse some code since we're doing similar things, but the sanitizer approach is simpler. Adding the new sinks should be easier than I initially thought, then :) |
java/ql/src/semmle/code/java/security/AndroidSensitiveBroadcastQuery.qll
Outdated
Show resolved
Hide resolved
java/ql/test/query-tests/security/CWE-927/SensitiveBroadcast.ql
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some more comments regarding CSV models. This covers the Intent extras pretty nicely, and the rest of the Intent methods (like get/setPackage) are or can be handled in other PRs like #6397.
Also, this will need a doc review at some point.
4062949
to
cd7a8a7
Compare
javaGenerated file changes for java
- Android,``android.*``,18,34,70,,,3,67,,,
+ Android,``android.*``,18,148,70,,,3,67,,,
- Totals,,116,3554,402,13,6,10,107,33,1,66
+ Totals,,116,3668,402,13,6,10,107,33,1,66
- android.content,8,,4,,,,,,,,,,,,,8,,,,,,4,
+ android.content,8,,44,,,,,,,,,,,,,8,,,,,,4,40
+ android.os,,,74,,,,,,,,,,,,,,,,,,,2,72 |
@joefarebrother this has conflicts |
java/ql/src/semmle/code/java/security/AndroidSensitiveBroadcastQuery.qll
Outdated
Show resolved
Hide resolved
} | ||
} | ||
|
||
private predicate isNullArg(Expr ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bad name (this indicates may-be-null, not is-null).
Also simplify this and isEmptyArrayArg
using DataFlow::localExprFlow
} | ||
|
||
/** | ||
* Holds if a `sendBroadcast` call doesn't specify receiver permission. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Holds if a `sendBroadcast` call doesn't specify receiver permission. | |
* Holds if a `sendBroadcast` call `sendBroadcastCall` doesn't specify receiver permission. |
/** | ||
* Holds if a `sendBroadcast` call doesn't specify receiver permission. | ||
*/ | ||
private predicate isSensitiveBroadcastSink(DataFlow::Node sink) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private predicate isSensitiveBroadcastSink(DataFlow::Node sink) { | |
private predicate isSensitiveBroadcastSink(DataFlow::Node sendBroadcastCall) { |
override predicate isSanitizer(DataFlow::Node node) { | ||
exists(MethodAccess setReceiverMa | | ||
setReceiverMa.getMethod().hasName(["setPackage", "setClass", "setClassName", "setComponent"]) and | ||
setReceiverMa.getQualifier().(VarAccess).getVariable().getAnAccess() = node.asExpr() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use localFlow instead of specifically one layer of access? Or (check by experiment) this might work just sanitising the qualifier due to use-use dataflow allowing sanitisers like this to interrupt dataflow paths to subsequent uses
(For example, in l = in; l.append("a"); l.append("b")
, in Java the dataflow edges go in -> l
, defn of l -> use of l in l.append("a")
, use of l in l.append("a") -> use of l in l.append("b")
, rather than both uses flowing from the definition as you might suppose)
"android.os;Bundle;true;putSizeF;;;Argument[0];MapKey of Argument[-1];value", | ||
"android.os;Bundle;true;putSparseParcelableArray;;;Argument[1];MapValue of Argument[-1];value", | ||
"android.os;Bundle;true;putStringArrayList;;;Argument[1];MapValue of Argument[-1];value", | ||
"android.content;Intent;true;getExtras;();;SyntheticField[android.content.Intent.extras] of Argument[-1];ReturnValue;value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
The context and class of the Intent can also be determined at construction time so the sanitizer needs to account for that. Something like: // Handle the cases where the PackageContext and Class are set at construction time
// Intent(Context packageContext, Class<?> cls)
// Create an intent for a specific component.
// Intent(String action, Uri uri, Context packageContext, Class<?> cls)
exists(ConstructorCall cc |
cc.getConstructedType() instanceof TypeIntent and
cc.getNumArgument() > 1 and
(
cc.getArgument(0).getType() instanceof TypeContext and
not exists(Expr classArg |
classArg instanceof NullLiteral and DataFlow::localExprFlow(classArg, cc.getArgument(1))
)
or
cc.getArgument(2).getType() instanceof TypeContext and
not exists(Expr classArg |
classArg instanceof NullLiteral and DataFlow::localExprFlow(classArg, cc.getArgument(3))
)
) and
DataFlow::localExprFlow(cc, node.asExpr())
) |
There is also the case when the broadcast receiver is determined dynamically. An attacker can abuse the intent filter priority to make it the first available receiver. The current sanitizers would ignore this case as setClassName or setPackage are usually called. I don't have the skills to propose a query for this case though. Intent intent = new Intent("com.victim.ADD_CARD_ACTION");
intent.putExtra("credit_card_number", num.getText().toString());
intent.putExtra("holder_name", name.getText().toString());
//...
for(ResolveInfo info : getPackageManager().queryBroadcastReceivers(intent, 0)) {
intent.setClassName(info.activityInfo.packageName, info.activityInfo.name);
sendBroadcast(intent);
return;
} |
0511a17
to
e815405
Compare
Additional models have been split into #6739 |
javaGenerated file changes for java
- Android,``android.*``,18,94,70,,,3,67,,,
+ Android,``android.*``,18,208,70,,,3,67,,,
- Totals,,116,4169,402,13,6,10,107,33,1,66
+ Totals,,116,4283,402,13,6,10,107,33,1,66
- android.content,8,,4,,,,,,,,,,,,,8,,,,,,4,
+ android.content,8,,44,,,,,,,,,,,,,8,,,,,,4,40
+ android.os,,,74,,,,,,,,,,,,,,,,,,,2,72 |
e815405
to
b6c584c
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests are failing, and I added a minor inline comment. Otherwise, LGTM.
@@ -84,6 +84,7 @@ private module Frameworks { | |||
private import semmle.code.java.frameworks.apache.Collections | |||
private import semmle.code.java.frameworks.apache.Lang | |||
private import semmle.code.java.frameworks.Flexjson | |||
private import semmle.code.java.frameworks.android.Intent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicates import in line 81.
private import semmle.code.java.frameworks.android.Intent |
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
Hi everyone 👋🏻 - Docs First Responder here, thanks for the ping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. A couple of little editorial suggestions. 👍
@@ -0,0 +1,21 @@ | |||
/** | |||
* @name Leaking sensitive information through an implicit Intent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, use lowercase for intent - as elsewhere:
* @name Leaking sensitive information through an implicit Intent | |
* @name Leaking sensitive information through an implicit intent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't Intent
the name of the class? I'm not sure this should be lower-cased.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If so we should make it Intent throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it's the name of a class (just like Activity
or Service
), so I would use uppercase everywhere. Since there's more Android work coming, maybe a dedicated PR standardizing capitalization for this kind of thing in all files is due.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's fix the query name and change note of this query here in this PR instead of postponing these particular instances to a dedicated PR. Even if we need a general sweep to standardize, I don't think we should add to those needed changes.
Co-authored-by: hubwriter <hubwriter@github.com>
java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll
Outdated
Show resolved
Hide resolved
java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll
Show resolved
Hide resolved
I had set myself as a reviewer for this this morning and had actually started a review, but as this has been already reviewed by a Docs team member, I'll unassign myself 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As suggested by @aschackmull and @hubwriter, let's capitalize the first letter in all occurrences of terms like Intent, Activity or Service.
java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll
Outdated
Show resolved
Hide resolved
java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@atorralba - thanks for suggesting those changes.
LGTM 👍
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
This PR promotes the query contributed by #4512 from experimental.
Changes:
SensitiveBroadcastQuery.qll
Intent
andBundle
sendStickyBroadcast
methods as additional sinksConsiderations:
A similar vulnerability is in sending sensitive data via methods likestartActivity
andstartService
. Should sinks for those be part of this same query?Should the additional models be a separate PR?