Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 99c79f4

Browse files
committed
Enhance the dataflow sink and update test cases
1 parent 07830aa commit 99c79f4

4 files changed

Lines changed: 82 additions & 56 deletions

File tree

java/ql/src/experimental/Security/CWE/CWE-927/SensitiveBroadcast.ql

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,10 @@
88
*/
99

1010
import java
11-
import semmle.code.java.frameworks.android.Intent
11+
import semmle.code.java.dataflow.DataFlow3
1212
import semmle.code.java.dataflow.TaintTracking
13-
14-
/**
15-
* Gets a regular expression for matching common names of variables that indicate the value being held contains sensitive information.
16-
*/
17-
private string getCommonSensitiveInfoRegex() {
18-
result = "(?i).*challenge|pass(wd|word|code|phrase)(?!.*question).*" or
19-
result = "(?i).*(token|username|userid|secret).*"
20-
}
13+
import semmle.code.java.frameworks.android.Intent
14+
import semmle.code.java.security.SensitiveActions
2115

2216
/**
2317
* Gets regular expression for matching names of Android variables that indicate the value being held contains sensitive information.
@@ -48,16 +42,13 @@ class PutBundleExtraMethodAccess extends MethodAccess {
4842
class SensitiveInfoExpr extends Expr {
4943
SensitiveInfoExpr() {
5044
exists(Variable v | this = v.getAnAccess() |
51-
(
52-
v.getName().toLowerCase().regexpMatch(getCommonSensitiveInfoRegex()) or
53-
v.getName().toLowerCase().regexpMatch(getAndroidSensitiveInfoRegex())
54-
)
45+
v.getName().regexpMatch([getCommonSensitiveInfoRegex(), getAndroidSensitiveInfoRegex()])
5546
)
5647
}
5748
}
5849

5950
/**
60-
* The method access of `context.sendBroadcast`.
51+
* A method access of the `context.sendBroadcast` family.
6152
*/
6253
class SendBroadcastMethodAccess extends MethodAccess {
6354
SendBroadcastMethodAccess() {
@@ -71,17 +62,21 @@ private class NullArgFlowConfig extends DataFlow2::Configuration {
7162

7263
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof NullLiteral }
7364

74-
override predicate isSink(DataFlow::Node sink) { any() }
65+
override predicate isSink(DataFlow::Node sink) {
66+
exists(SendBroadcastMethodAccess ma | sink.asExpr() = ma.getAnArgument())
67+
}
7568
}
7669

77-
private class EmptyArrayArgFlowConfig extends DataFlow2::Configuration {
70+
private class EmptyArrayArgFlowConfig extends DataFlow3::Configuration {
7871
EmptyArrayArgFlowConfig() { this = "Flow configuration with an empty array argument" }
7972

8073
override predicate isSource(DataFlow::Node src) {
8174
src.asExpr().(ArrayCreationExpr).getFirstDimensionSize() = 0
8275
}
8376

84-
override predicate isSink(DataFlow::Node sink) { any() }
77+
override predicate isSink(DataFlow::Node sink) {
78+
exists(SendBroadcastMethodAccess ma | sink.asExpr() = ma.getAnArgument())
79+
}
8580
}
8681

8782
/**
@@ -110,7 +105,7 @@ predicate isSensitiveBroadcastSink(DataFlow::Node sink) {
110105
config.hasFlow(_, DataFlow::exprNode(ma.getArgument(1))) // sendBroadcastWithMultiplePermissions(Intent intent, String[] receiverPermissions)
111106
)
112107
or
113-
//Method calls of `sendOrderedBroadcast` whose second argument is always `receiverPermission`
108+
// Method calls of `sendOrderedBroadcast` whose second argument is always `receiverPermission`
114109
ma.getMethod().hasName("sendOrderedBroadcast") and
115110
(
116111
// sendOrderedBroadcast(Intent intent, String receiverPermission) or sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
@@ -123,7 +118,7 @@ predicate isSensitiveBroadcastSink(DataFlow::Node sink) {
123118
ma.getNumArgument() = 8
124119
)
125120
or
126-
//Method call of `sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)`
121+
// Method call of `sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)`
127122
ma.getMethod().hasName("sendOrderedBroadcastAsUser") and
128123
exists(NullArgFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(ma.getArgument(2))))
129124
)

java/ql/src/semmle/code/java/security/SensitiveActions.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ private string nonSuspicious() {
2727
result = "%crypt%"
2828
}
2929

30+
/**
31+
* Gets a regular expression for matching common names of variables that indicate the value being held contains sensitive information.
32+
*/
33+
string getCommonSensitiveInfoRegex() {
34+
result = "(?i).*challenge|pass(wd|word|code|phrase)(?!.*question).*" or
35+
result = "(?i).*(token|username|userid|secret).*"
36+
}
37+
3038
/** An expression that might contain sensitive data. */
3139
abstract class SensitiveExpr extends Expr { }
3240

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
| SensitiveBroadcast.java:13:31:13:36 | intent | SensitiveBroadcast.java:11:34:11:38 | token : String | SensitiveBroadcast.java:13:31:13:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:11:34:11:38 | token | sensitive information |
22
| SensitiveBroadcast.java:13:31:13:36 | intent | SensitiveBroadcast.java:12:41:12:52 | refreshToken : String | SensitiveBroadcast.java:13:31:13:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:12:41:12:52 | refreshToken | sensitive information |
3-
| SensitiveBroadcast.java:25:31:25:36 | intent | SensitiveBroadcast.java:23:33:23:40 | username : String | SensitiveBroadcast.java:25:31:25:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:23:33:23:40 | username | sensitive information |
3+
| SensitiveBroadcast.java:25:31:25:36 | intent | SensitiveBroadcast.java:23:33:23:40 | userName : String | SensitiveBroadcast.java:25:31:25:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:23:33:23:40 | userName | sensitive information |
44
| SensitiveBroadcast.java:25:31:25:36 | intent | SensitiveBroadcast.java:24:32:24:39 | password : String | SensitiveBroadcast.java:25:31:25:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:24:32:24:39 | password | sensitive information |
5-
| SensitiveBroadcast.java:39:31:39:36 | intent | SensitiveBroadcast.java:36:40:36:47 | username : String | SensitiveBroadcast.java:39:31:39:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:36:40:36:47 | username | sensitive information |
6-
| SensitiveBroadcast.java:39:31:39:36 | intent | SensitiveBroadcast.java:37:39:37:46 | password : String | SensitiveBroadcast.java:39:31:39:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:37:39:37:46 | password | sensitive information |
7-
| SensitiveBroadcast.java:89:54:89:59 | intent | SensitiveBroadcast.java:87:33:87:40 | username : String | SensitiveBroadcast.java:89:54:89:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:87:33:87:40 | username | sensitive information |
8-
| SensitiveBroadcast.java:89:54:89:59 | intent | SensitiveBroadcast.java:88:32:88:39 | password : String | SensitiveBroadcast.java:89:54:89:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:88:32:88:39 | password | sensitive information |
9-
| SensitiveBroadcast.java:102:54:102:59 | intent | SensitiveBroadcast.java:99:33:99:40 | username : String | SensitiveBroadcast.java:102:54:102:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:99:33:99:40 | username | sensitive information |
10-
| SensitiveBroadcast.java:102:54:102:59 | intent | SensitiveBroadcast.java:100:32:100:39 | password : String | SensitiveBroadcast.java:102:54:102:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:100:32:100:39 | password | sensitive information |
11-
| SensitiveBroadcast.java:116:54:116:59 | intent | SensitiveBroadcast.java:112:33:112:40 | username : String | SensitiveBroadcast.java:116:54:116:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:112:33:112:40 | username | sensitive information |
12-
| SensitiveBroadcast.java:116:54:116:59 | intent | SensitiveBroadcast.java:113:32:113:39 | password : String | SensitiveBroadcast.java:116:54:116:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:113:32:113:39 | password | sensitive information |
5+
| SensitiveBroadcast.java:37:31:37:36 | intent | SensitiveBroadcast.java:35:41:35:45 | email : String | SensitiveBroadcast.java:37:31:37:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:35:41:35:45 | email | sensitive information |
6+
| SensitiveBroadcast.java:49:31:49:36 | intent | SensitiveBroadcast.java:47:33:47:40 | username : String | SensitiveBroadcast.java:49:31:49:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:47:33:47:40 | username | sensitive information |
7+
| SensitiveBroadcast.java:49:31:49:36 | intent | SensitiveBroadcast.java:48:32:48:39 | password : String | SensitiveBroadcast.java:49:31:49:36 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:48:32:48:39 | password | sensitive information |
8+
| SensitiveBroadcast.java:95:54:95:59 | intent | SensitiveBroadcast.java:94:35:94:40 | ticket : String | SensitiveBroadcast.java:95:54:95:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:94:35:94:40 | ticket | sensitive information |
9+
| SensitiveBroadcast.java:108:54:108:59 | intent | SensitiveBroadcast.java:105:33:105:40 | username : String | SensitiveBroadcast.java:108:54:108:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:105:33:105:40 | username | sensitive information |
10+
| SensitiveBroadcast.java:108:54:108:59 | intent | SensitiveBroadcast.java:106:32:106:39 | password : String | SensitiveBroadcast.java:108:54:108:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:106:32:106:39 | password | sensitive information |
11+
| SensitiveBroadcast.java:139:54:139:59 | intent | SensitiveBroadcast.java:134:40:134:47 | username : String | SensitiveBroadcast.java:139:54:139:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:134:40:134:47 | username | sensitive information |
12+
| SensitiveBroadcast.java:139:54:139:59 | intent | SensitiveBroadcast.java:135:39:135:46 | password : String | SensitiveBroadcast.java:139:54:139:59 | intent | Sending $@ to broadcast. | SensitiveBroadcast.java:135:39:135:46 | password | sensitive information |

java/ql/test/experimental/query-tests/security/CWE-927/SensitiveBroadcast.java

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
class SensitiveBroadcast {
66

7-
//Tests broadcast of access token with intent extra.
7+
// BAD - Tests broadcast of access token with intent extra.
88
public void sendBroadcast1(Context context, String token, String refreshToken) {
99
Intent intent = new Intent();
1010
intent.setAction("com.example.custom_action");
@@ -13,33 +13,31 @@ public void sendBroadcast1(Context context, String token, String refreshToken) {
1313
context.sendBroadcast(intent);
1414
}
1515

16-
//Tests broadcast of sensitive user information with intent extra.
16+
// BAD - Tests broadcast of sensitive user information with intent extra.
1717
public void sendBroadcast2(Context context) {
18-
String username = "test123";
18+
String userName = "test123";
1919
String password = "abc12345";
2020

2121
Intent intent = new Intent();
2222
intent.setAction("com.example.custom_action");
23-
intent.putExtra("name", username);
23+
intent.putExtra("name", userName);
2424
intent.putExtra("pwd", password);
2525
context.sendBroadcast(intent);
2626
}
2727

28-
//Tests broadcast of sensitive user information with extra bundle.
28+
// BAD - Tests broadcast of email information with extra bundle.
2929
public void sendBroadcast3(Context context) {
30-
String username = "test123";
31-
String password = "abc12345";
30+
String email = "[email protected]";
3231

3332
Intent intent = new Intent();
3433
intent.setAction("com.example.custom_action");
3534
Bundle bundle = new Bundle();
36-
bundle.putCharSequence("name", username);
37-
bundle.putCharSequence("pwd", password);
35+
bundle.putCharSequence("email", email);
3836
intent.putExtras(bundle);
3937
context.sendBroadcast(intent);
4038
}
4139

42-
//Tests broadcast of sensitive user information with permission using string literal.
40+
// BAD - Tests broadcast of sensitive user information with null permission.
4341
public void sendBroadcast4(Context context) {
4442
String username = "test123";
4543
String password = "abc12345";
@@ -48,10 +46,10 @@ public void sendBroadcast4(Context context) {
4846
intent.setAction("com.example.custom_action");
4947
intent.putExtra("name", username);
5048
intent.putExtra("pwd", password);
51-
context.sendBroadcast(intent, "com.example.user_permission");
49+
context.sendBroadcast(intent, null);
5250
}
5351

54-
//Tests broadcast of sensitive user information with permission using string object.
52+
// GOOD - Tests broadcast of sensitive user information with permission using string literal.
5553
public void sendBroadcast5(Context context) {
5654
String username = "test123";
5755
String password = "abc12345";
@@ -60,12 +58,22 @@ public void sendBroadcast5(Context context) {
6058
intent.setAction("com.example.custom_action");
6159
intent.putExtra("name", username);
6260
intent.putExtra("pwd", password);
61+
context.sendBroadcast(intent, "com.example.user_permission");
62+
}
63+
64+
// GOOD - Tests broadcast of access ticket with permission using string object.
65+
public void sendBroadcast6(Context context) {
66+
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
67+
68+
Intent intent = new Intent();
69+
intent.setAction("com.example.custom_action");
70+
intent.putExtra("ticket", ticket);
6371
String perm = "com.example.user_permission";
6472
context.sendBroadcast(intent, perm);
6573
}
6674

67-
//Tests broadcast of sensitive user information to a specific application.
68-
public void sendBroadcast6(Context context) {
75+
// GOOD - Tests broadcast of sensitive user information to a specific application.
76+
public void sendBroadcast7(Context context) {
6977
String username = "test123";
7078
String password = "abc12345";
7179

@@ -77,20 +85,18 @@ public void sendBroadcast6(Context context) {
7785
context.sendBroadcast(intent);
7886
}
7987

80-
//Tests broadcast of sensitive user information with multiple permissions using direct empty array initialization.
81-
public void sendBroadcast7(Context context) {
82-
String username = "test123";
83-
String password = "abc12345";
88+
// BAD - Tests broadcast of access ticket with multiple permissions using direct empty array initialization.
89+
public void sendBroadcast8(Context context) {
90+
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
8491

8592
Intent intent = new Intent();
8693
intent.setAction("com.example.custom_action");
87-
intent.putExtra("name", username);
88-
intent.putExtra("pwd", password);
94+
intent.putExtra("ticket", ticket);
8995
context.sendBroadcastWithMultiplePermissions(intent, new String[]{});
9096
}
9197

92-
//Tests broadcast of sensitive user information with multiple permissions using empty array initialization through a variable.
93-
public void sendBroadcast8(Context context) {
98+
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through a variable.
99+
public void sendBroadcast9(Context context) {
94100
String username = "test123";
95101
String password = "abc12345";
96102

@@ -102,22 +108,39 @@ public void sendBroadcast8(Context context) {
102108
context.sendBroadcastWithMultiplePermissions(intent, perms);
103109
}
104110

105-
//Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables.
106-
public void sendBroadcast9(Context context) {
111+
// GOOD - Tests broadcast of sensitive user information with multiple permissions.
112+
public void sendBroadcast10(Context context) {
107113
String username = "test123";
108114
String password = "abc12345";
109115

110116
Intent intent = new Intent();
111117
intent.setAction("com.example.custom_action");
112-
intent.putExtra("name", username);
113-
intent.putExtra("pwd", password);
118+
Bundle bundle = new Bundle();
119+
bundle.putCharSequence("name", username);
120+
bundle.putCharSequence("pwd", password);
121+
intent.putExtras(bundle);
122+
String[] perms = new String[]{"com.example.custom_action", "com.example.custom_action2"};
123+
context.sendBroadcastWithMultiplePermissions(intent, perms);
124+
}
125+
126+
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables.
127+
public void sendBroadcast11(Context context) {
128+
String username = "test123";
129+
String password = "abc12345";
130+
131+
Intent intent = new Intent();
132+
intent.setAction("com.example.custom_action");
133+
Bundle bundle = new Bundle();
134+
bundle.putCharSequence("name", username);
135+
bundle.putCharSequence("pwd", password);
136+
intent.putExtras(bundle);
114137
String[] perms = new String[0];
115138
String[] perms2 = perms;
116139
context.sendBroadcastWithMultiplePermissions(intent, perms2);
117140
}
118141

119-
//Tests broadcast of sensitive user information with ordered broadcast.
120-
public void sendBroadcast10(Context context) {
142+
// GOOD - Tests broadcast of sensitive user information with ordered broadcast.
143+
public void sendBroadcast12(Context context) {
121144
String username = "test123";
122145
String password = "abc12345";
123146

0 commit comments

Comments
 (0)