/* TEMPLATE GENERATED TESTCASE FILE Filename: CWE90_LDAP_Injection__Servlet_listen_tcp_16.java Label Definition File: CWE90_LDAP_Injection__Servlet.label.xml Template File: sources-sink-16.tmpl.java */ /* * @description * CWE: 90 LDAP Injection * BadSource: listen_tcp Read data using a listening tcp connection * GoodSource: A hardcoded string * BadSink: unchecked data leads to LDAP injection * Flow Variant: 16 Control flow: while(true) and while(local_f) * * */ package testcases.CWE90_LDAP_Injection; import testcasesupport.*; import javax.naming.*; import javax.naming.directory.*; import javax.servlet.http.*; import java.util.Hashtable; import java.io.IOException; import org.apache.commons.lang.StringEscapeUtils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.net.Socket; import java.net.ServerSocket; import java.util.logging.Logger; public class CWE90_LDAP_Injection__Servlet_listen_tcp_16 extends AbstractTestCaseServlet { /* uses badsource and badsink */ public void bad(HttpServletRequest request, HttpServletResponse response) throws Throwable { String data; boolean local_f = false; /* This local variable is used becuase the Java compiler will generate an error on while(false) and similar constructs that evaluate to false. This is the simplest construct that will always be false and still compile. */ while(local_f) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ java.util.logging.Logger log_good = java.util.logging.Logger.getLogger("local-logger"); /* FIX: Use a hardcoded string */ data = "foo"; } while(true) { Logger log_bad = Logger.getLogger("local-logger"); data = ""; /* init data */ /* Read data using a listening tcp connection */ ServerSocket listener = null; Socket sock = null; BufferedReader buffread = null; InputStreamReader instrread = null; try { /* read input from socket */ listener = new ServerSocket(39543); sock = listener.accept(); instrread = new InputStreamReader(sock.getInputStream()); buffread = new BufferedReader(instrread); data = buffread.readLine(); } catch( IOException ioe ) { log_bad.warning("Error with stream reading"); } finally { /* clean up stream reading objects */ try { if( buffread != null ) { buffread.close(); } } catch( IOException ioe ) { log_bad.warning("Error closing buffread"); } finally { try { if( instrread != null ) { instrread.close(); } } catch( IOException ioe ) { log_bad.warning("Error closing instrread"); } } /* clean up socket objects */ try { if( sock != null ) { sock.close(); } } catch( IOException e ) { log_bad.warning("Error closing sock"); } finally { try { if( listener != null ) { listener.close(); } } catch( IOException e ) { log_bad.warning("Error closing listener"); } } } break; } Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); DirContext ctx = new InitialDirContext(env); String search = "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */ NamingEnumeration answer = ctx.search("", search, null); while (answer.hasMore()) { SearchResult sr = answer.next(); Attributes a = sr.getAttributes(); NamingEnumeration attrs = a.getAll(); while (attrs.hasMore()) { Attribute attr = (Attribute) attrs.next(); NamingEnumeration values = attr.getAll(); while(values.hasMore()) { response.getWriter().println(" Value: " + values.next().toString()); } } } } /* goodG2B() - use goodsource and badsink by changing the conditions on the while statements */ private void goodG2B(HttpServletRequest request, HttpServletResponse response) throws Throwable { String data; boolean local_f = false; while(true) { java.util.logging.Logger log_good = java.util.logging.Logger.getLogger("local-logger"); /* FIX: Use a hardcoded string */ data = "foo"; break; } while(local_f) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ Logger log_bad = Logger.getLogger("local-logger"); data = ""; /* init data */ /* Read data using a listening tcp connection */ ServerSocket listener = null; Socket sock = null; BufferedReader buffread = null; InputStreamReader instrread = null; try { /* read input from socket */ listener = new ServerSocket(39543); sock = listener.accept(); instrread = new InputStreamReader(sock.getInputStream()); buffread = new BufferedReader(instrread); data = buffread.readLine(); } catch( IOException ioe ) { log_bad.warning("Error with stream reading"); } finally { /* clean up stream reading objects */ try { if( buffread != null ) { buffread.close(); } } catch( IOException ioe ) { log_bad.warning("Error closing buffread"); } finally { try { if( instrread != null ) { instrread.close(); } } catch( IOException ioe ) { log_bad.warning("Error closing instrread"); } } /* clean up socket objects */ try { if( sock != null ) { sock.close(); } } catch( IOException e ) { log_bad.warning("Error closing sock"); } finally { try { if( listener != null ) { listener.close(); } } catch( IOException e ) { log_bad.warning("Error closing listener"); } } } break; } Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); DirContext ctx = new InitialDirContext(env); String search = "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */ NamingEnumeration answer = ctx.search("", search, null); while (answer.hasMore()) { SearchResult sr = answer.next(); Attributes a = sr.getAttributes(); NamingEnumeration attrs = a.getAll(); while (attrs.hasMore()) { Attribute attr = (Attribute) attrs.next(); NamingEnumeration values = attr.getAll(); while(values.hasMore()) { response.getWriter().println(" Value: " + values.next().toString()); } } } } public void good(HttpServletRequest request, HttpServletResponse response) throws Throwable { goodG2B(request, response); } /* Below is the main(). It is only used when building this testcase on its own for testing or for building a binary to use in testing binary analysis tools. It is not used when compiling all the testcases as one application, which is how source code analysis tools are tested. */ public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { mainFromParent(args); } }