22// http://cwe.mitre.org/data/definitions/807.html
33package test .cwe807 .semmle .tests ;
44
5-
6-
7-
85import java .net .InetAddress ;
96import java .net .Inet4Address ;
107import java .net .UnknownHostException ;
118
129import javax .servlet .http .Cookie ;
10+ import javax .servlet .http .HttpServletRequest ;
1311import org .apache .shiro .SecurityUtils ;
1412import org .apache .shiro .subject .Subject ;
1513
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+
2321 // BAD: login is only executed if isAdmin is false, but isAdmin
2422 // is controlled by the user
25- if (isAdmin == "false" )
23+ if (isAdmin == "false" ) // $ hasConditionalBypassTest
2624 login (user , password );
27-
25+
2826 Cookie adminCookie = getCookies ()[0 ];
2927 // BAD: login is only executed if the cookie value is false, but the cookie
3028 // is controlled by the user
31- if (adminCookie .getValue ().equals ("false" ))
29+ if (adminCookie .getValue ().equals ("false" )) // $ hasConditionalBypassTest
3230 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
3533 // both perform the security-critical action
36- if (adminCookie .getValue ()== "false" ) {
34+ if (adminCookie .getValue () == "false" ) { // Safe
3735 login (user , password );
3836 } else {
3937 reCheckAuth (user , password );
4038 }
41-
39+
4240 // 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
4442 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+
5744 InetAddress local = InetAddress .getLocalHost ();
5845 // GOOD: reverse DNS on localhost is fine
5946 if (local .getCanonicalHostName ().equals ("localhost" )) {
@@ -63,68 +50,129 @@ public static void main(String[] args) throws UnknownHostException {
6350 login (user , password );
6451 }
6552 }
66-
53+
6754 public static void test (String user , String password ) {
6855 Cookie adminCookie = getCookies ()[0 ];
6956 // GOOD: login always happens
70- if (adminCookie .getValue ()== "false" )
57+ if (adminCookie .getValue () == "false" )
7158 login (user , password );
7259 else {
73- // do something else
7460 login (user , password );
7561 }
7662 }
77-
63+
7864 public static void test2 (String user , String password ) {
7965 Cookie adminCookie = getCookies ()[0 ];
8066 // BAD: login may happen once or twice
81- if (adminCookie .getValue ()== "false" )
67+ if (adminCookie .getValue () == "false" ) // $ hasConditionalBypassTest
8268 login (user , password );
8369 else {
8470 // do something else
71+ doIt ();
8572 }
8673 login (user , password );
8774 }
88-
75+
8976 public static void test3 (String user , String password ) {
9077 Cookie adminCookie = getCookies ()[0 ];
91- if (adminCookie .getValue ()=="false" )
78+ // BAD: login may not happen
79+ if (adminCookie .getValue () == "false" ) // $ hasConditionalBypassTest
9280 login (user , password );
9381 else {
9482 // do something else
95- // BAD: login may not happen
96- return ;
83+ doIt ();
9784 }
85+ return ;
9886 }
99-
87+
10088 public static void test4 (String user , String password ) {
10189 Cookie adminCookie = getCookies ()[0 ];
10290 // GOOD: login always happens
103- if (adminCookie .getValue ()== "false" ) {
91+ if (adminCookie .getValue () == "false" ) {
10492 login (user , password );
10593 return ;
10694 }
107-
95+
10896 // do other things
10997 login (user , password );
11098 return ;
11199 }
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+
113153 public static void login (String user , String password ) {
114154 // login
115155 }
116-
156+
117157 public static void reCheckAuth (String user , String password ) {
118158 // login
119159 }
120-
160+
161+ public static void authorize (String user , String password ) {
162+ // login
163+ }
164+
165+ public static String obtainAuthor () {
166+ return "" ;
167+ }
168+
121169 public static Cookie [] getCookies () {
122170 // get cookies from a servlet
123171 return new Cookie [0 ];
124172 }
125-
173+
126174 public static void doIt () {}
127-
175+
128176 public static void doReallyImportantSecurityWork () {
129177 // login, authenticate, everything
130178 }
0 commit comments