Skip to content

Commit 031bd8b

Browse files
Merge pull request #15281 from joefarebrother/android-sensitive-ui-notif
Java: Add query for exposure of sensitive information to android notifiactions
2 parents 73130ec + dedba1f commit 031bd8b

33 files changed

+887
-596
lines changed

java/ql/lib/ext/android.app.model.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,48 @@ extensions:
3030
- ["android.app", "FragmentTransaction", True, "replace", "(int,Class,Bundle,String)", "", "Argument[1]", "fragment-injection", "manual"]
3131
- ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment)", "", "Argument[1]", "fragment-injection", "manual"]
3232
- ["android.app", "FragmentTransaction", True, "replace", "(int,Fragment,String)", "", "Argument[1]", "fragment-injection", "manual"]
33+
- ["android.app", "Notification$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
34+
- ["android.app", "Notification$Action$Builder", True, "Builder", "(Icon,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
35+
- ["android.app", "Notification$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
36+
- ["android.app", "Notification$Action$Builder", True, "addExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
37+
- ["android.app", "Notification$BigPictureStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
38+
- ["android.app", "Notification$BigPictureStyle", True, "setContentDescription", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
39+
- ["android.app", "Notification$BigPictureStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
40+
- ["android.app", "Notification$BigTextStyle", True, "bigText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
41+
- ["android.app", "Notification$BigTextStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
42+
- ["android.app", "Notification$BigTextStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
43+
- ["android.app", "Notification$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
44+
- ["android.app", "Notification$Builder", True, "addExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
45+
- ["android.app", "Notification$Builder", True, "setCategory", "(String)", "", "Argument[0]", "notification", "manual"]
46+
- ["android.app", "Notification$Builder", True, "setChannelId", "(String)", "", "Argument[0]", "notification", "manual"]
47+
- ["android.app", "Notification$Builder", True, "setContent", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
48+
- ["android.app", "Notification$Builder", True, "setContentInfo", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
49+
- ["android.app", "Notification$Builder", True, "setContentText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
50+
- ["android.app", "Notification$Builder", True, "setContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
51+
- ["android.app", "Notification$Builder", True, "setCustomBigContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
52+
- ["android.app", "Notification$Builder", True, "setCustomContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
53+
- ["android.app", "Notification$Builder", True, "setCustomHeadsUpContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
54+
- ["android.app", "Notification$Builder", True, "setExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
55+
- ["android.app", "Notification$Builder", True, "setGroup", "(String)", "", "Argument[0]", "notification", "manual"]
56+
- ["android.app", "Notification$Builder", True, "setRemoteInputHistory", "(CharSequence[])", "", "Argument[0]", "notification", "manual"]
57+
- ["android.app", "Notification$Builder", True, "setSettingsText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
58+
- ["android.app", "Notification$Builder", True, "setSortKey", "(String)", "", "Argument[0]", "notification", "manual"]
59+
- ["android.app", "Notification$Builder", True, "setSubText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
60+
- ["android.app", "Notification$Builder", True, "setTicker", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
61+
- ["android.app", "Notification$Builder", True, "setTicker", "(CharSequence,RemoteViews)", "", "Argument[0..1]", "notification", "manual"]
62+
- ["android.app", "Notification$CallStyle", True, "setVerificationText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
63+
- ["android.app", "Notification$InboxStyle", True, "addLine", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
64+
- ["android.app", "Notification$InboxStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
65+
- ["android.app", "Notification$InboxStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
66+
- ["android.app", "Notification$MediaStyle", True, "setRemotePlaybackInfo", "(CharSequence,int,PendingIntent)", "", "Argument[0]", "notification", "manual"]
67+
- ["android.app", "Notification$MessagingStyle", True, "MessagingStyle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
68+
- ["android.app", "Notification$MessagingStyle", True, "addMessage", "(CharSequence,long,CharSequence)", "", "Argument[0]", "notification", "manual"]
69+
- ["android.app", "Notification$MessagingStyle", True, "addMessage", "(CharSequence,long,CharSequence)", "", "Argument[2]", "notification", "manual"]
70+
- ["android.app", "Notification$MessagingStyle", True, "addMessage", "(CharSequence,long,Person)", "", "Argument[0]", "notification", "manual"]
71+
- ["android.app", "Notification$MessagingStyle", True, "setConversationTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
72+
- ["android.app", "Notification$MessagingStyle$Message", True, "Message", "(CharSequence,long,CharSequence)", "", "Argument[0]", "notification", "manual"]
73+
- ["android.app", "Notification$MessagingStyle$Message", True, "Message", "(CharSequence,long,CharSequence)", "", "Argument[2]", "notification", "manual"]
74+
- ["android.app", "Notification$MessagingStyle$Message", True, "Message", "(CharSequence,long,Person)", "", "Argument[0]", "notification", "manual"]
3375
- ["android.app", "NotificationManager", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intents", "manual"]
3476
- ["android.app", "NotificationManager", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intents", "manual"]
3577
- ["android.app", "NotificationManager", True, "notifyAsPackage", "(String,String,int,Notification)", "", "Argument[3]", "pending-intents", "manual"]
@@ -38,6 +80,7 @@ extensions:
3880
- ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,PendingIntent$OnFinished,Handler)", "", "Argument[2]", "pending-intents", "manual"]
3981
- ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,PendingIntent$OnFinished,Handler,String)", "", "Argument[2]", "pending-intents", "manual"]
4082
- ["android.app", "PendingIntent", False, "send", "(Context,int,Intent,PendingIntent$OnFinished,Handler,String,Bundle)", "", "Argument[2]", "pending-intents", "manual"]
83+
4184
- addsTo:
4285
pack: codeql/java-all
4386
extensible: summaryModel

java/ql/lib/ext/androidx.core.app.model.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,50 @@ extensions:
77
- ["androidx.core.app", "AlarmManagerCompat", True, "setAndAllowWhileIdle", "", "", "Argument[3]", "pending-intents", "manual"]
88
- ["androidx.core.app", "AlarmManagerCompat", True, "setExact", "", "", "Argument[3]", "pending-intents", "manual"]
99
- ["androidx.core.app", "AlarmManagerCompat", True, "setExactAndAllowWhileIdle", "", "", "Argument[3]", "pending-intents", "manual"]
10+
- ["androidx.core.app", "NotificationCompat$Action", True, "Action", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
11+
- ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(IconCompat,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
12+
- ["androidx.core.app", "NotificationCompat$Action$Builder", True, "Builder", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
13+
- ["androidx.core.app", "NotificationCompat$Action$Builder", True, "addExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
14+
- ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
15+
- ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setContentDescription", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
16+
- ["androidx.core.app", "NotificationCompat$BigPictureStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
17+
- ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "bigText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
18+
- ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
19+
- ["androidx.core.app", "NotificationCompat$BigTextStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
20+
- ["androidx.core.app", "NotificationCompat$Builder", True, "addAction", "(int,CharSequence,PendingIntent)", "", "Argument[1]", "notification", "manual"]
21+
- ["androidx.core.app", "NotificationCompat$Builder", True, "addExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
22+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setCategory", "(String)", "", "Argument[0]", "notification", "manual"]
23+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setChannelId", "(String)", "", "Argument[0]", "notification", "manual"]
24+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setContent", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
25+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setContentInfo", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
26+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setContentText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
27+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
28+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomBigContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
29+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
30+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setCustomHeadsUpContentView", "(RemoteViews)", "", "Argument[0]", "notification", "manual"]
31+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setExtras", "(Bundle)", "", "Argument[0]", "notification", "manual"]
32+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setGroup", "(String)", "", "Argument[0]", "notification", "manual"]
33+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setRemoteInputHistory", "(CharSequence[])", "", "Argument[0]", "notification", "manual"]
34+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setSettingsText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
35+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setSortKey", "(String)", "", "Argument[0]", "notification", "manual"]
36+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setSubText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
37+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setTicker", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
38+
- ["androidx.core.app", "NotificationCompat$Builder", True, "setTicker", "(CharSequence,RemoteViews)", "", "Argument[0..1]", "notification", "manual"]
39+
- ["androidx.core.app", "NotificationCompat$CallStyle", True, "setVerificationText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
40+
- ["androidx.core.app", "NotificationCompat$InboxStyle", True, "addLine", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
41+
- ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setBigContentTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
42+
- ["androidx.core.app", "NotificationCompat$InboxStyle", True, "setSummaryText", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
43+
- ["androidx.core.app", "NotificationCompat$MessagingStyle", True, "addMessage", "(CharSequence,long,CharSequence)", "", "Argument[0]", "notification", "manual"]
44+
- ["androidx.core.app", "NotificationCompat$MessagingStyle", True, "addMessage", "(CharSequence,long,CharSequence)", "", "Argument[2]", "notification", "manual"]
45+
- ["androidx.core.app", "NotificationCompat$MessagingStyle", True, "addMessage", "(CharSequence,long,Person)", "", "Argument[0]", "notification", "manual"]
46+
- ["androidx.core.app", "NotificationCompat$MessagingStyle", True, "setConversationTitle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
47+
- ["androidx.core.app", "NotificationCompat$MessagingStyle", True, "MessagingStyle", "(CharSequence)", "", "Argument[0]", "notification", "manual"]
48+
- ["androidx.core.app", "NotificationCompat$MessagingStyle$Message", True, "Message", "(CharSequence,long,CharSequence)", "", "Argument[0]", "notification", "manual"]
49+
- ["androidx.core.app", "NotificationCompat$MessagingStyle$Message", True, "Message", "(CharSequence,long,CharSequence)", "", "Argument[2]", "notification", "manual"]
50+
- ["androidx.core.app", "NotificationCompat$MessagingStyle$Message", True, "Message", "(CharSequence,long,Person)", "", "Argument[0]", "notification", "manual"]
1051
- ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(String,int,Notification)", "", "Argument[2]", "pending-intents", "manual"]
1152
- ["androidx.core.app", "NotificationManagerCompat", True, "notify", "(int,Notification)", "", "Argument[1]", "pending-intents", "manual"]
53+
1254
- addsTo:
1355
pack: codeql/java-all
1456
extensible: summaryModel
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/** Definitions for Android Sensitive UI queries */
2+
3+
import java
4+
private import semmle.code.java.dataflow.ExternalFlow
5+
private import semmle.code.java.dataflow.TaintTracking
6+
private import semmle.code.java.security.SensitiveActions
7+
8+
/** A configuration for tracking sensitive information to system notifications. */
9+
private module NotificationTrackingConfig implements DataFlow::ConfigSig {
10+
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr }
11+
12+
predicate isSink(DataFlow::Node sink) { sinkNode(sink, "notification") }
13+
14+
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
15+
isSink(node) and exists(c)
16+
}
17+
18+
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
19+
}
20+
21+
/** Taint tracking flow for sensitive data flowing to system notifications. */
22+
module NotificationTracking = TaintTracking::Global<NotificationTrackingConfig>;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// BAD: `password` is exposed in a notification.
2+
void confirmPassword(String password) {
3+
NotificationManager manager = NotificationManager.from(this);
4+
manager.send(
5+
new Notification.Builder(this, CHANNEL_ID)
6+
.setContentText("Your password is: " + password)
7+
.build());
8+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>
7+
Sensitive information such as passwords or two-factor authentication (2FA) codes should not be exposed in a system notification.
8+
Notifications should not be considered secure, as other untrusted applications may be able to use a
9+
<code>NotificationListenerService</code> to read the contents of notifications.
10+
</p>
11+
</overview>
12+
13+
<recommendation>
14+
<p>
15+
Do not expose sensitive data in notifications.
16+
</p>
17+
</recommendation>
18+
19+
<example>
20+
<p>
21+
In the following sample, the <code>password</code> is sent as part of a notification.
22+
This can allow another application to read this password.
23+
</p>
24+
25+
<sample src="AndroidSensitiveNotifications.java"/>
26+
</example>
27+
28+
<references>
29+
<li>
30+
OWASP Mobile Application Security: <a href="https://mas.owasp.org/MASTG/Android/0x05d-Testing-Data-Storage/#app-notifications">Android Data Storage - Application Notifications</a>
31+
</li>
32+
</references>
33+
34+
</qhelp>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @name Exposure of sensitive information to notifications
3+
* @id java/android/sensitive-notification
4+
* @kind path-problem
5+
* @description Sensitive information exposed in a system notification can be read by an unauthorized application.
6+
* @problem.severity error
7+
* @precision medium
8+
* @security-severity 6.5
9+
* @tags security
10+
* external/cwe/cwe-200
11+
*/
12+
13+
import java
14+
import java
15+
import semmle.code.java.security.SensitiveUiQuery
16+
import NotificationTracking::PathGraph
17+
18+
from NotificationTracking::PathNode source, NotificationTracking::PathNode sink
19+
where NotificationTracking::flowPath(source, sink)
20+
select sink, source, sink, "This $@ is exposed in a system notification.", source,
21+
"sensitive information"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: newQuery
3+
---
4+
* Added a new query `java/android/sensitive-notification` to detect instances of sensitive data being exposed through Android notifications.

0 commit comments

Comments
 (0)