2
2
// http://cwe.mitre.org/data/definitions/807.html
3
3
package test .cwe807 .semmle .tests ;
4
4
5
-
6
-
7
-
8
5
import java .net .InetAddress ;
9
6
import java .net .Inet4Address ;
10
7
import java .net .UnknownHostException ;
11
8
12
9
import javax .servlet .http .Cookie ;
10
+ import javax .servlet .http .HttpServletRequest ;
13
11
import org .apache .shiro .SecurityUtils ;
14
12
import org .apache .shiro .subject .Subject ;
15
13
16
- class Test {
17
- public static void main (String [] args ) throws UnknownHostException {
18
- String user = args [ 0 ] ;
19
- String password = args [ 1 ] ;
20
-
21
- String isAdmin = args [ 3 ] ;
22
-
14
+ class ConditionalBypassTest {
15
+ public static void main (HttpServletRequest request ) throws Exception {
16
+ String user = request . getParameter ( "user" ) ;
17
+ String password = request . getParameter ( "password" ) ;
18
+
19
+ String isAdmin = request . getParameter ( "isAdmin" ) ;
20
+
23
21
// BAD: login is only executed if isAdmin is false, but isAdmin
24
22
// is controlled by the user
25
- if (isAdmin == "false" )
23
+ if (isAdmin == "false" ) // $ hasConditionalBypassTest
26
24
login (user , password );
27
-
25
+
28
26
Cookie adminCookie = getCookies ()[0 ];
29
27
// BAD: login is only executed if the cookie value is false, but the cookie
30
28
// is controlled by the user
31
- if (adminCookie .getValue ().equals ("false" ))
29
+ if (adminCookie .getValue ().equals ("false" )) // $ hasConditionalBypassTest
32
30
login (user , password );
33
-
34
- // FALSE POSITIVES : both methods are conditionally executed, but they probably
31
+
32
+ // GOOD : both methods are conditionally executed, but they probably
35
33
// both perform the security-critical action
36
- if (adminCookie .getValue ()== "false" ) {
34
+ if (adminCookie .getValue () == "false" ) { // Safe
37
35
login (user , password );
38
36
} else {
39
37
reCheckAuth (user , password );
40
38
}
41
-
39
+
42
40
// FALSE NEGATIVE: we have no way of telling that the skipped method is sensitive
43
- if (adminCookie .getValue ()== "false" )
41
+ if (adminCookie .getValue () == "false" ) // $ MISSING: $ hasConditionalBypassTest
44
42
doReallyImportantSecurityWork ();
45
-
46
- // Apache Shiro permissions system
47
- String whatDoTheyWantToDo = args [4 ];
48
- Subject subject = SecurityUtils .getSubject ();
49
- // BAD: permissions decision made using tainted data
50
- if (subject .isPermitted ("domain:sublevel:" + whatDoTheyWantToDo ))
51
- doIt ();
52
-
53
- // GOOD: use fixed checks
54
- if (subject .isPermitted ("domain:sublevel:whatTheMethodDoes" ))
55
- doIt ();
56
-
43
+
57
44
InetAddress local = InetAddress .getLocalHost ();
58
45
// GOOD: reverse DNS on localhost is fine
59
46
if (local .getCanonicalHostName ().equals ("localhost" )) {
@@ -63,68 +50,129 @@ public static void main(String[] args) throws UnknownHostException {
63
50
login (user , password );
64
51
}
65
52
}
66
-
53
+
67
54
public static void test (String user , String password ) {
68
55
Cookie adminCookie = getCookies ()[0 ];
69
56
// GOOD: login always happens
70
- if (adminCookie .getValue ()== "false" )
57
+ if (adminCookie .getValue () == "false" )
71
58
login (user , password );
72
59
else {
73
- // do something else
74
60
login (user , password );
75
61
}
76
62
}
77
-
63
+
78
64
public static void test2 (String user , String password ) {
79
65
Cookie adminCookie = getCookies ()[0 ];
80
66
// BAD: login may happen once or twice
81
- if (adminCookie .getValue ()== "false" )
67
+ if (adminCookie .getValue () == "false" ) // $ hasConditionalBypassTest
82
68
login (user , password );
83
69
else {
84
70
// do something else
71
+ doIt ();
85
72
}
86
73
login (user , password );
87
74
}
88
-
75
+
89
76
public static void test3 (String user , String password ) {
90
77
Cookie adminCookie = getCookies ()[0 ];
91
- if (adminCookie .getValue ()=="false" )
78
+ // BAD: login may not happen
79
+ if (adminCookie .getValue () == "false" ) // $ hasConditionalBypassTest
92
80
login (user , password );
93
81
else {
94
82
// do something else
95
- // BAD: login may not happen
96
- return ;
83
+ doIt ();
97
84
}
85
+ return ;
98
86
}
99
-
87
+
100
88
public static void test4 (String user , String password ) {
101
89
Cookie adminCookie = getCookies ()[0 ];
102
90
// GOOD: login always happens
103
- if (adminCookie .getValue ()== "false" ) {
91
+ if (adminCookie .getValue () == "false" ) {
104
92
login (user , password );
105
93
return ;
106
94
}
107
-
95
+
108
96
// do other things
109
97
login (user , password );
110
98
return ;
111
99
}
112
-
100
+
101
+ public static void test5 (String user , String password ) throws Exception {
102
+ Cookie adminCookie = getCookies ()[0 ];
103
+ // GOOD: exit with Exception if condition is not met
104
+ if (adminCookie .getValue () == "false" ) {
105
+ throw new Exception ();
106
+ }
107
+
108
+ login (user , password );
109
+ }
110
+
111
+ public static void test6 (String user , String password ) {
112
+ Cookie adminCookie = getCookies ()[0 ];
113
+ // GOOD: exit with return if condition is not met
114
+ if (adminCookie .getValue () == "false" ) {
115
+ return ;
116
+ }
117
+
118
+ login (user , password );
119
+ }
120
+
121
+ public static void test7 (String user , String password ) {
122
+ Cookie adminCookie = getCookies ()[0 ];
123
+ // BAD: login is bypasseable
124
+ if (adminCookie .getValue () == "false" ) { // $ hasConditionalBypassTest
125
+ login (user , password );
126
+ return ;
127
+ } else {
128
+ doIt ();
129
+ }
130
+ }
131
+
132
+ public static void test8 (String user , String password ) {
133
+ Cookie adminCookie = getCookies ()[0 ];
134
+ {
135
+ // BAD: login may not happen
136
+ if (adminCookie .getValue () == "false" ) // $ hasConditionalBypassTest
137
+ authorize (user , password );
138
+ else {
139
+ // do something else
140
+ doIt ();
141
+ }
142
+ }
143
+ {
144
+ // obtainAuthor is not sensitive, so this is safe
145
+ if (adminCookie .getValue () == "false" )
146
+ obtainAuthor ();
147
+ else {
148
+ doIt ();
149
+ }
150
+ }
151
+ }
152
+
113
153
public static void login (String user , String password ) {
114
154
// login
115
155
}
116
-
156
+
117
157
public static void reCheckAuth (String user , String password ) {
118
158
// login
119
159
}
120
-
160
+
161
+ public static void authorize (String user , String password ) {
162
+ // login
163
+ }
164
+
165
+ public static String obtainAuthor () {
166
+ return "" ;
167
+ }
168
+
121
169
public static Cookie [] getCookies () {
122
170
// get cookies from a servlet
123
171
return new Cookie [0 ];
124
172
}
125
-
173
+
126
174
public static void doIt () {}
127
-
175
+
128
176
public static void doReallyImportantSecurityWork () {
129
177
// login, authenticate, everything
130
178
}
0 commit comments