| @@ -0,0 +1,56 @@ | |||||
| package Command_Injection; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class Command_Injection | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public Process bad() | |||||
| { | |||||
| String data = System.getProperty("ADD"); | |||||
| String osCommand = "c:\\WINDOWS\\SYSTEM32\\cmd.exe /c dir "; | |||||
| Process p = null; | |||||
| try { | |||||
| p = Runtime.getRuntime().exec(osCommand + data); // bad 命令注入 | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| return p; | |||||
| } | |||||
| public Process good() | |||||
| { | |||||
| String data = System.getProperty("ADD"); | |||||
| String osCommand = "c:\\WINDOWS\\SYSTEM32\\cmd.exe /c dir "; | |||||
| data = SafeCheck(data); | |||||
| Process p = null; | |||||
| if(!data.equals("bad")){ | |||||
| try { | |||||
| p = Runtime.getRuntime().exec(osCommand + data); // good 命令注入 | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| } | |||||
| return p; | |||||
| } | |||||
| public String SafeCheck(String input){ | |||||
| if("good".equals(input)){ | |||||
| return "foo"; | |||||
| }else{ | |||||
| return "bad"; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package Create_Boolean_Object; | |||||
| import java.util.logging.Logger; | |||||
| public class Create_Boolean_Object { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() { | |||||
| boolean bl = new Boolean(true); // bad 创建Boolean对象 | |||||
| log.info("create " + bl); | |||||
| } | |||||
| public void good() { | |||||
| boolean bl = Boolean.TRUE; // good 创建Boolean对象 | |||||
| log.info("create " + bl); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package Create_String_Object; | |||||
| import java.util.logging.Logger; | |||||
| public class Create_String_Object { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() { | |||||
| String bl = new String("test"); // bad 创建String对象 | |||||
| log.info("create " + bl); | |||||
| } | |||||
| public void good() { | |||||
| String bl = "test"; // good 创建String对象 | |||||
| log.info("create " + bl); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,21 @@ | |||||
| package Debug_Code; | |||||
| import java.util.logging.Logger; | |||||
| public class Debug_Code_bad { | |||||
| public Debug_Code_bad() { | |||||
| Logger log = Logger.getLogger("logger"); | |||||
| log.info("debug code"); | |||||
| } | |||||
| public static void main(String[] args){ // bad 遗留的调试信息 | |||||
| Logger log = Logger.getLogger("logger"); | |||||
| log.info("debug code"); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,21 @@ | |||||
| package Debug_Code; | |||||
| import java.util.logging.Logger; | |||||
| public class Debug_Code_good { // good 遗留的调试信息 | |||||
| public Debug_Code_good() { | |||||
| Logger log = Logger.getLogger("logger"); | |||||
| log.info("debug code"); | |||||
| } | |||||
| // public static void main(String[] args){ | |||||
| // Logger log = Logger.getLogger("logger"); | |||||
| // log.info("debug code"); | |||||
| // } | |||||
| } | |||||
| @@ -0,0 +1,31 @@ | |||||
| package Empty_Catch_Block; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| public class Empty_Catch_Block { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response){ | |||||
| try { | |||||
| response.getWriter().write("You cannot shut down this application, only the admin can"); | |||||
| } catch (IOException e) { // bad 空的catch代码块 | |||||
| log.info("bad"); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response){ | |||||
| try { | |||||
| response.getWriter().write("You cannot shut down this application, only the admin can"); | |||||
| } catch (IOException e) { // good 空的catch代码块 | |||||
| log.info("bad"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package Empty_If_Block; | |||||
| public class Empty_If_Block { | |||||
| public String bad(String input) { | |||||
| if (input.length() == 0) { // bad 空的if代码块 | |||||
| } | |||||
| return ""; | |||||
| } | |||||
| public String good(String input) { | |||||
| if (input.length() == 0) { // good 空的if代码块 | |||||
| return ""; | |||||
| } else{ | |||||
| return input; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package Empty_Password; | |||||
| public class Empty_Password { | |||||
| public String bad(){ | |||||
| String password = ""; // bad 空密码 | |||||
| return password; | |||||
| } | |||||
| public String good(String user,String pass){ | |||||
| if(pass.length()!=0){ | |||||
| String password = pass; // good 空密码 | |||||
| return password; | |||||
| }else | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| package Empty_String_Compare; | |||||
| public class Empty_String_Compare { | |||||
| public String bad(String input) { | |||||
| if(input.equals("")){ // bad 空字符串比较 | |||||
| return ""; | |||||
| }else{ | |||||
| return input; | |||||
| } | |||||
| } | |||||
| public String good(String input) { | |||||
| if(input.length() == 0){ // good 空字符串比较 | |||||
| return ""; | |||||
| }else{ | |||||
| return input; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| package Empty_Syn_Block; | |||||
| import java.util.logging.Logger; | |||||
| public class Empty_Syn_Block { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() | |||||
| { | |||||
| Integer a = 1; | |||||
| synchronized (a) { // bad 空的同步代码块 | |||||
| } | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| Object object = new Object(); | |||||
| synchronized (object) { // good 空的同步代码块 | |||||
| log.info("OK"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| package Expression_Always_False; | |||||
| import java.util.logging.Logger; | |||||
| public class Expression_Always_False_01 | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() | |||||
| { | |||||
| /* FLAW: always evaluates to false */ | |||||
| boolean tag = false; | |||||
| if(tag) // bad 表达式永远为false | |||||
| { | |||||
| log.info("never prints"); | |||||
| } | |||||
| } | |||||
| public void good(int j) | |||||
| { | |||||
| boolean tag = false; | |||||
| if(j == 1){ | |||||
| tag = true; | |||||
| } | |||||
| /* FIX: may evaluate to true or false */ | |||||
| if(tag) // good 表达式永远为false | |||||
| { | |||||
| log.info("sometimes prints"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| package Expression_Always_False; | |||||
| import java.util.logging.Logger; | |||||
| public class Expression_Always_False_02 | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() | |||||
| { | |||||
| /* FLAW: always evaluates to false */ | |||||
| if(1!=1) // bad 表达式永远为false | |||||
| { | |||||
| log.info("never prints"); | |||||
| } | |||||
| } | |||||
| public void good(int j) | |||||
| { | |||||
| boolean tag = false; | |||||
| if(j == 1){ | |||||
| tag = true; | |||||
| } | |||||
| /* FIX: may evaluate to true or false */ | |||||
| if(tag) // good 表达式永远为false | |||||
| { | |||||
| log.info("sometimes prints"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,37 @@ | |||||
| package Expression_Always_True; | |||||
| import java.util.logging.Logger; | |||||
| public class Expression_Always_True_01 | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() | |||||
| { | |||||
| /* FLAW: always evaluates to true */ | |||||
| boolean tag = true; | |||||
| if(tag) // bad 表达式永远为true | |||||
| { | |||||
| log.info("always prints"); | |||||
| } | |||||
| } | |||||
| public void good(int j) | |||||
| { | |||||
| boolean tag = true; | |||||
| if(j == 1){ | |||||
| tag = false; | |||||
| } | |||||
| /* FIX: may evaluate to true or false */ | |||||
| if(tag) // good 表达式永远为true | |||||
| { | |||||
| log.info("sometimes prints"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| package Expression_Always_True; | |||||
| import java.util.logging.Logger; | |||||
| public class Expression_Always_True_02 | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() | |||||
| { | |||||
| /* FLAW: always evaluates to true */ | |||||
| if(1==1) // bad 表达式永远为true | |||||
| { | |||||
| log.info("always prints"); | |||||
| } | |||||
| } | |||||
| public void good(int j) | |||||
| { | |||||
| boolean tag = true; | |||||
| if(j == 1){ | |||||
| tag = false; | |||||
| } | |||||
| /* FIX: may evaluate to true or false */ | |||||
| if(tag) // good 表达式永远为true | |||||
| { | |||||
| log.info("sometimes prints"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | |||||
| pageEncoding="ISO-8859-1"%> | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
| <html> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |||||
| <title>HTTP Splitting</title> | |||||
| </head> | |||||
| <body> | |||||
| <% response.sendRedirect("https://aa.com/test.php"); %> <%-- // good HTML Comment in JSP file --%> | |||||
| <!-- this is an html comment.it will show up int the response. --> <%-- // bad HTML Comment in JSP file --%> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,27 @@ | |||||
| package HTTP_Response_Splitting; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| public class HTTP_Response_Splitting { | |||||
| public void bad(HttpServletRequest request,HttpServletResponse response) | |||||
| { | |||||
| String value = request.getParameter("value"); | |||||
| String UNIQUE2U ="cookie"; | |||||
| response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HttpOnly"); // bad Http响应截断 | |||||
| } | |||||
| public void good(HttpServletRequest request,HttpServletResponse response) | |||||
| { | |||||
| String value = "author-cookie"; | |||||
| String UNIQUE2U ="cookie"; | |||||
| response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HttpOnly"); // good Http响应截断 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,65 @@ | |||||
| package Hard_Coded_Password; | |||||
| import java.security.InvalidKeyException; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.crypto.BadPaddingException; | |||||
| import javax.crypto.Cipher; | |||||
| import javax.crypto.IllegalBlockSizeException; | |||||
| import javax.crypto.NoSuchPaddingException; | |||||
| import javax.crypto.spec.SecretKeySpec; | |||||
| public class Hard_Coded_Password | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public String bad() | |||||
| { | |||||
| String password = "Password"; // bad 纭紪鐮佸瘑鐮� | |||||
| return password; | |||||
| } | |||||
| public String good() | |||||
| { | |||||
| String data = "key"; /* init data */ | |||||
| String sKey = "Skey"; | |||||
| Cipher cipher = null; | |||||
| String pw = ""; | |||||
| try { | |||||
| SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "AES"); | |||||
| cipher = Cipher.getInstance("AES"); | |||||
| cipher.init(Cipher.DECRYPT_MODE, key); | |||||
| }catch (NoSuchPaddingException e) { | |||||
| log.info("error"); | |||||
| }catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } catch (InvalidKeyException e) { | |||||
| log.info("InvalidKeyException"); | |||||
| } | |||||
| try { | |||||
| if(cipher != null){ | |||||
| pw = new String(cipher.doFinal(data.getBytes())); | |||||
| } | |||||
| } catch (IllegalBlockSizeException e) { | |||||
| log.info("error"); | |||||
| } catch (BadPaddingException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| String password = pw; // good 纭紪鐮佸瘑鐮� | |||||
| return password; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package Insecuere_Randomness; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| import java.security.SecureRandom; | |||||
| import java.util.Random; | |||||
| import java.util.logging.Logger; | |||||
| public class Insecuere_Randomness | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() | |||||
| { | |||||
| Random rand = new Random(); | |||||
| /* FLAW: seed is static, making the numbers always occur in the same sequence */ | |||||
| rand.setSeed(System.currentTimeMillis()); | |||||
| log.info("Random int: " + rand.nextInt(21)); // bad 不安全的随机数 | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| /* FIX: use SecureRandom to be cryptographically secure */ | |||||
| SecureRandom securerand; | |||||
| try { | |||||
| securerand = SecureRandom.getInstance("SHA1PRNG"); | |||||
| log.info("Random int: " + securerand.nextInt(21)); // good 不安全的随机数 | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("NoSuchAlgorithmException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,34 @@ | |||||
| package J2EE_Bad_Practices_Use_of_System_Exit; | |||||
| import javax.servlet.http.*; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class J2EE_Bad_Practices_Use_of_System_Exit__Servlet_01 | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| System.exit(1); // bad JAVA EE不良的实现:调用System.exit()或Runtime.exit()关闭应用程序容器 | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| try { | |||||
| response.getWriter().write("You cannot shut down this application, only the admin can"); | |||||
| } catch (IOException e) { | |||||
| log.info("error"); | |||||
| } // good JAVA EE不良的实现:调用System.exit()或Runtime.exit()关闭应用程序容器 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| package Just_one_of_Equals_or_hashCode_defined; | |||||
| public class Just_one_of_Equals_or_hashCode_defined_bad { | |||||
| int a; | |||||
| String b; | |||||
| public Just_one_of_Equals_or_hashCode_defined_bad(int a, String b) { | |||||
| this.a = a; | |||||
| this.b = b; | |||||
| } | |||||
| public boolean equals(Object o) { // bad 仅定义了equals方法或hashcode方法 | |||||
| Just_one_of_Equals_or_hashCode_defined_bad d = (Just_one_of_Equals_or_hashCode_defined_bad) o; | |||||
| if(d != null){ | |||||
| return (this.a == d.a) && (this.b.equals(d.b)); | |||||
| }else | |||||
| return false; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package Just_one_of_Equals_or_hashCode_defined; | |||||
| public class Just_one_of_Equals_or_hashCode_defined_good { // good 仅定义了equals方法或hashcode方法 | |||||
| int a; | |||||
| String b; | |||||
| public Just_one_of_Equals_or_hashCode_defined_good(int a, String b) { | |||||
| this.a = a; | |||||
| this.b = b; | |||||
| } | |||||
| public int hashCode() { | |||||
| return a * (b.hashCode()); | |||||
| } | |||||
| public boolean equals(Object o) { | |||||
| Just_one_of_Equals_or_hashCode_defined_good d = (Just_one_of_Equals_or_hashCode_defined_good) o; | |||||
| if(d!=null){ | |||||
| return (this.a == d.a) && (this.b.equals(d.b)); | |||||
| }else | |||||
| return false; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,55 @@ | |||||
| package LDAP_Injection; | |||||
| import javax.naming.*; | |||||
| import javax.naming.directory.*; | |||||
| import javax.servlet.http.*; | |||||
| import java.util.Hashtable; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class LDAP_Injection | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| /* uses badsource and badsink */ | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response) throws NamingException, IOException | |||||
| { | |||||
| String data = System.getProperty("data"); /* init data */ | |||||
| Hashtable<String, String> env = new Hashtable<String, String>(); | |||||
| 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<SearchResult> answer = ctx.search("", search, null); // bad LDAP注入 | |||||
| if (answer.hasMore()) | |||||
| { | |||||
| log.info("ok"); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response) throws NamingException, IOException | |||||
| { | |||||
| String data = "foo"; | |||||
| Hashtable<String, String> env = new Hashtable<String, String>(); | |||||
| 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<SearchResult> answer = ctx.search("", search, null); // good LDAP注入 | |||||
| if (answer.hasMore()) | |||||
| { | |||||
| log.info("ok"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package Log_Forging; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| public class Log_Forging { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request) { | |||||
| String val = request.getParameter("val"); | |||||
| try { | |||||
| int value = Integer.parseInt(val); | |||||
| if(value != 0){ | |||||
| log.info("parse ok"); | |||||
| } | |||||
| } | |||||
| catch (NumberFormatException e) { | |||||
| log.info("Failed to parse val = " + val); // bad 日志伪造 | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request) { | |||||
| String val = "1"; | |||||
| try { | |||||
| int value = Integer.parseInt(val); | |||||
| if(value != 0){ | |||||
| log.info("parse ok"); | |||||
| } | |||||
| } | |||||
| catch (NumberFormatException e) { | |||||
| log.info("Failed to parse val = " + val); // good 日志伪造 | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,20 @@ | |||||
| package Logging_using_System_output; | |||||
| import java.util.logging.Logger; | |||||
| public class Logging_using_System_output { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() | |||||
| { | |||||
| System.out.println("write log"); // bad 系统输出流记录日志 | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| log.info("write log"); // good 系统输出流记录日志 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,60 @@ | |||||
| package Null_Password; | |||||
| import java.security.InvalidKeyException; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.crypto.BadPaddingException; | |||||
| import javax.crypto.Cipher; | |||||
| import javax.crypto.IllegalBlockSizeException; | |||||
| import javax.crypto.NoSuchPaddingException; | |||||
| import javax.crypto.spec.SecretKeySpec; | |||||
| public class Null_Password { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public String bad() { | |||||
| String password = null; // bad null密码 | |||||
| return password; | |||||
| } | |||||
| public String good() | |||||
| { | |||||
| String data = "key"; /* init data */ | |||||
| String sKey = "Skey"; | |||||
| Cipher cipher = null; | |||||
| String pw = ""; | |||||
| try { | |||||
| SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "AES"); | |||||
| cipher = Cipher.getInstance("AES"); | |||||
| cipher.init(Cipher.DECRYPT_MODE, key); | |||||
| }catch (NoSuchPaddingException e) { | |||||
| log.info("error"); | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } catch (InvalidKeyException e) { | |||||
| log.info("InvalidKeyException"); | |||||
| } | |||||
| try { | |||||
| if(cipher != null){ | |||||
| pw = new String(cipher.doFinal(data.getBytes())); | |||||
| } | |||||
| } catch (IllegalBlockSizeException e) { | |||||
| log.info("error"); | |||||
| } catch (BadPaddingException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| String password = pw; // good null密码 | |||||
| return password; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package Obsolete_Method; | |||||
| public class Obsolete_Method { | |||||
| public String bad() { | |||||
| String data; | |||||
| data = System.getenv("ADD"); // bad 废弃的方法 | |||||
| return data; | |||||
| } | |||||
| public String good() { | |||||
| String data; | |||||
| data = System.getProperty("ADD"); // good 废弃的方法 | |||||
| return data; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,6 @@ | |||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" import="java.util.regex.*" | |||||
| pageEncoding="ISO-8859-1"%> | |||||
| <% | |||||
| String strDest = request.getParameter("dest"); | |||||
| pageContext.forward(strDest); %> <%-- // good Open Redirect --%> | |||||
| @@ -0,0 +1,8 @@ | |||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" import="java.util.regex.*" | |||||
| pageEncoding="ISO-8859-1"%> | |||||
| <% | |||||
| String[] strURLArray = new String[]{"http://aa.com","http://bb.com","http://cc.com"}; | |||||
| int strDest = Integer.parseInt(request.getParameter("dest")); | |||||
| if((strDest >= 0) && (strDest <= 15 )) | |||||
| { String strFinalURL = strURLArray[strDest]; | |||||
| pageContext.forward(strFinalURL); } %> <%-- // good Open Redirect --%> | |||||
| @@ -0,0 +1,41 @@ | |||||
| package Overly_board_Catch; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| public class Overly_board_Catch { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request){ | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(Exception e){ // bad 犯化的捕获异常 | |||||
| log.info("Exception"); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request) { | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(NumberFormatException e){ // good 犯化的捕获异常 | |||||
| log.info("NumberFormatException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| package Overly_board_Throws; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| public class Overly_board_Throws { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request) throws Throwable { // bad 犯化的抛出异常 | |||||
| String val = "1"; | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) | |||||
| log.info("parse ok"); | |||||
| } | |||||
| public void good(HttpServletRequest request) throws NumberFormatException { // good 犯化的抛出异常 | |||||
| String val = "1"; | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package Path_Manipulate; | |||||
| import java.io.File; | |||||
| public class Path_Manipulate { | |||||
| public void bad(){ | |||||
| String path = System.getProperty("dir"); | |||||
| File f = new File(path); // bad 路径遍历 | |||||
| f.delete(); | |||||
| } | |||||
| public void good(){ | |||||
| String path = "C:" + File.separator + "test.txt"; | |||||
| File f = new File(path); // good 路径遍历 | |||||
| f.delete(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,85 @@ | |||||
| package Persist_XSS; | |||||
| import javax.servlet.http.*; | |||||
| import java.sql.Connection; | |||||
| import java.sql.PreparedStatement; | |||||
| import java.sql.ResultSet; | |||||
| import java.sql.SQLException; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class Persist_XSS | |||||
| { | |||||
| public PreparedStatement statement = null; | |||||
| public ResultSet rs = null; | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response,Connection conn) | |||||
| { | |||||
| String data = ""; /* init data */ | |||||
| try { | |||||
| statement = conn.prepareStatement("select name from users where name = 'lily'"); | |||||
| rs = statement.executeQuery(); | |||||
| data = rs.getString(1); | |||||
| } catch (SQLException e1) { | |||||
| log.info("SQLException"); | |||||
| }finally { | |||||
| try { | |||||
| rs.close(); | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| try { | |||||
| statement.close(); | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| try { | |||||
| conn.close(); | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| } | |||||
| if (data != null) | |||||
| { | |||||
| /* POTENTIAL FLAW: data not validated */ | |||||
| try { | |||||
| response.getWriter().println("<br>bad() - Parameter name has value " + data); // bad 存储型XSS | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| String data; | |||||
| /* FIX: Use a hardcoded string */ | |||||
| data = "foo"; | |||||
| /* POTENTIAL FLAW: data not validated */ | |||||
| try { | |||||
| response.getWriter().println("<br>bad() - Parameter name has value " + data); // good 存储型XSS | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package Redundence_Initialize; | |||||
| import java.util.logging.Logger; | |||||
| public class Redundence_Initialize { | |||||
| static final Logger log = Logger.getLogger("log"); | |||||
| public void bad() { | |||||
| String a = ""; // bad 冗余的初始化 | |||||
| a = getString(); | |||||
| log.info(a); | |||||
| } | |||||
| public static String getString(){ | |||||
| return "redundence_initialize"; | |||||
| } | |||||
| public void good() { | |||||
| String a = "123"; // good 冗余的初始化 | |||||
| log.info(a); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" import="java.util.regex.*" | |||||
| pageEncoding="ISO-8859-1"%> | |||||
| <% | |||||
| String action = request.getParameter("action"); | |||||
| String field1 = request.getParameter("field1"); | |||||
| String regex1 = "^[0-9]{3}$";// any three digits | |||||
| Pattern pattern1 = Pattern.compile(regex1); | |||||
| if("Purchase".equals(action)) | |||||
| { | |||||
| if(!pattern1.matcher(field1).matches()) | |||||
| { | |||||
| /** If they supplied the right attack, pass them **/ | |||||
| out.write("alert('Whoops: You entered an incorrect access code of \"" + field1 + "\"');"); // bad XSS | |||||
| } | |||||
| } | |||||
| %> | |||||
| @@ -0,0 +1,20 @@ | |||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" import="java.util.regex.*" | |||||
| pageEncoding="ISO-8859-1"%> | |||||
| <% | |||||
| String action = request.getParameter("action"); | |||||
| String field1 = "field1"; | |||||
| String regex1 = "^[0-9]{3}$";// any three digits | |||||
| Pattern pattern1 = Pattern.compile(regex1); | |||||
| if("Purchase".equals(action)) | |||||
| { | |||||
| if(!pattern1.matcher(field1).matches()) | |||||
| { | |||||
| /** If they supplied the right attack, pass them **/ | |||||
| out.write("alert('Whoops: You entered an incorrect access code of \"" + field1 + "\"');"); // good xss | |||||
| } | |||||
| } | |||||
| %> | |||||
| @@ -0,0 +1,51 @@ | |||||
| package Return_in_Finally; | |||||
| import java.util.logging.Logger; | |||||
| public class Return_in_Finally | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad() | |||||
| { | |||||
| try | |||||
| { | |||||
| throw new IllegalArgumentException(); | |||||
| } | |||||
| catch(IllegalArgumentException iae) | |||||
| { | |||||
| log.info("preventing incidental issues"); | |||||
| } | |||||
| finally | |||||
| { | |||||
| /* return; // bad finally块中的return语句 | |||||
| /* INCIDENTAL: 571 Always returns true */ | |||||
| /* We need the "if(true)" above because the Java Language Spec requires that unreachable code generate a compiler error */ | |||||
| log.info("In finally block, cleaning up"); | |||||
| } | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| try | |||||
| { | |||||
| throw new IllegalArgumentException(); | |||||
| } | |||||
| catch(IllegalArgumentException iae) | |||||
| { | |||||
| log.info("preventing incidental issues"); | |||||
| } | |||||
| finally | |||||
| { | |||||
| /* FIX: cleanup code here and continue */ | |||||
| log.info("In finally block, cleaning up"); // good finally块中的return语句 | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,126 @@ | |||||
| package SQL_Injection; | |||||
| import java.sql.*; | |||||
| import javax.servlet.http.*; | |||||
| import java.util.logging.Logger; | |||||
| public class SQL_Injection | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response,Connection conn) | |||||
| { | |||||
| Connection conn_tmp2 = null; | |||||
| Statement sqlstatement = null; | |||||
| String data = System.getProperty("sql-input"); | |||||
| try { | |||||
| conn_tmp2 = conn; | |||||
| sqlstatement = conn_tmp2.createStatement(); | |||||
| /* POTENTIAL FLAW: value of "name" taken directly from an untrusted source and inserted into a command string executed against a SQL interpreter */ | |||||
| Boolean bResult = sqlstatement.execute("insert into users (status) values ('updated') where name='" + data + "'"); // bad SQL注入 | |||||
| if( bResult ) | |||||
| { | |||||
| log.info("updated successfully"); | |||||
| } | |||||
| else | |||||
| { | |||||
| log.info("Unable to update records"); | |||||
| } | |||||
| } | |||||
| catch( SQLException se ) | |||||
| { | |||||
| log.info("Error getting database connection"); | |||||
| } | |||||
| finally { | |||||
| try { | |||||
| if( sqlstatement != null ) | |||||
| { | |||||
| sqlstatement.close(); | |||||
| } | |||||
| } | |||||
| catch( SQLException e ) | |||||
| { | |||||
| log.info("Error closing sqlstatement"); | |||||
| } | |||||
| finally { | |||||
| try { | |||||
| if( conn_tmp2 != null ) | |||||
| { | |||||
| conn_tmp2.close(); | |||||
| } | |||||
| } | |||||
| catch( SQLException e ) | |||||
| { | |||||
| log.info("Error closing conn_tmp2"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response,Connection conn) | |||||
| { | |||||
| String data; | |||||
| /* FIX: Use a hardcoded string */ | |||||
| data = "foo"; | |||||
| Connection conn_tmp2 = null; | |||||
| Statement sqlstatement = null; | |||||
| try { | |||||
| conn_tmp2 = conn; | |||||
| sqlstatement = conn_tmp2.createStatement(); | |||||
| Boolean bResult = sqlstatement.execute("insert into users (status) values ('updated') where name='"+data+"'"); // good SQL注入 | |||||
| if( bResult ) | |||||
| { | |||||
| log.info("updated successfully"); | |||||
| } | |||||
| else | |||||
| { | |||||
| log.info("Unable to update records"); | |||||
| } | |||||
| } | |||||
| catch( SQLException se ) | |||||
| { | |||||
| log.info("Error getting database connection"); | |||||
| } | |||||
| finally { | |||||
| try { | |||||
| if( sqlstatement != null ) | |||||
| { | |||||
| sqlstatement.close(); | |||||
| } | |||||
| } | |||||
| catch( SQLException e ) | |||||
| { | |||||
| log.info("Error closing sqlstatement"); | |||||
| } | |||||
| finally { | |||||
| try { | |||||
| if( conn_tmp2 != null ) | |||||
| { | |||||
| conn_tmp2.close(); | |||||
| } | |||||
| } | |||||
| catch( SQLException e ) | |||||
| { | |||||
| log.info("Error closing conn_tmp2"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| package Static_Field_Not_Final; | |||||
| public class Static_Field_Not_Final | |||||
| { | |||||
| /* FLAW: public static fields should be marked final */ | |||||
| public static final String defaultError = "The value you entered was not understood. Please try again."; // bad 非final的public static字段 | |||||
| public static final String defaultRight = "GOOD"; // good 非final的public static字段 | |||||
| public void bad() { } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package String_Compare_Error; | |||||
| public class String_Compare_Error { | |||||
| public String bad(String input) { | |||||
| if (input != "test") { // bad 字符串比较错误 | |||||
| return "not empty"; | |||||
| } | |||||
| return "bad"; | |||||
| } | |||||
| public String good(String input) { | |||||
| if (input.equals("test")) { // good 字符串比较错误 | |||||
| return "not empty"; | |||||
| } else{ | |||||
| return "good"; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package Stringbuild_in_loop; | |||||
| public class Stringbuild_in_loop { | |||||
| public void Stringbuild_in_loop_bad() { | |||||
| String a = "test"; | |||||
| for (int i = 0; i < 5; i++) { | |||||
| a = a + "<br>"; // bad 循环中拼接字符串 | |||||
| } | |||||
| } | |||||
| public void Stringbuild_in_loop_good() { | |||||
| StringBuilder a = new StringBuilder("test"); | |||||
| for (int i = 0; i < 5; i++) { | |||||
| a.append("<br>"); // good 循环中拼接字符串 | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,44 @@ | |||||
| package System_Information_Leak; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class System_Information_Leak | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() throws IOException{ | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(NumberFormatException e){ | |||||
| e.printStackTrace(); // bad 系统信息泄露 | |||||
| } | |||||
| } | |||||
| public void good() { | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(NumberFormatException e){ | |||||
| log.info("NumberFormatException"); | |||||
| }finally{ | |||||
| log.info("complete"); // good 系统信息泄露 | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,44 @@ | |||||
| package Throws_Excepiton_in_Finally; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| public class Throws_Excepiton_in_Finally { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() throws IOException{ | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(NumberFormatException e){ | |||||
| log.info("NumberFormatException"); | |||||
| }finally{ // bad finally代码块中抛出异常 | |||||
| throw new IOException(); | |||||
| } | |||||
| } | |||||
| public void good() { | |||||
| String val = "1"; | |||||
| try{ | |||||
| int value = Integer.parseInt(val); | |||||
| if (value != 0) { | |||||
| log.info("parse ok"); | |||||
| } | |||||
| }catch(NumberFormatException e){ | |||||
| log.info("NumberFormatException"); | |||||
| }finally{ // good finally代码块中抛出异常 | |||||
| log.info("complete"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| package Trust_Boundary_Violation; | |||||
| import java.io.IOException; | |||||
| import javax.servlet.ServletException; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| import javax.servlet.http.HttpSession; | |||||
| public class Trust_Boundary_Violation { | |||||
| protected void bad(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | |||||
| String name = req.getParameter("userName"); | |||||
| HttpSession sess = req.getSession(); | |||||
| sess.setAttribute("user", name); // bad 数据跨越信任边界 | |||||
| } | |||||
| protected void good(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | |||||
| String name = req.getParameter("userName"); | |||||
| HttpSession sess = req.getSession(); | |||||
| name = SafeCheck(name); | |||||
| if(name.equals("admin")){ | |||||
| sess.setAttribute("user", name); // good 数据跨越信任边界 | |||||
| }else | |||||
| return; | |||||
| } | |||||
| public String SafeCheck(String input){ | |||||
| if("admin".equals(input)){ | |||||
| return "admin"; | |||||
| }else{ | |||||
| return "baduser"; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package Unchecked_Return_Value; | |||||
| import java.io.File; | |||||
| public class Unchecked_Return_Value { | |||||
| public String bad() { | |||||
| String filePath = "C:" + File.separator + "test" ; | |||||
| File f = new File(filePath); | |||||
| f.mkdir(); // bad 忽略返回值 | |||||
| return "ok"; | |||||
| } | |||||
| public String good() { | |||||
| String filePath = "C:" + File.separator + "test" ; | |||||
| File f = new File(filePath); | |||||
| boolean tag = f.mkdir(); // good 忽略返回值 | |||||
| if(tag){ | |||||
| return "ok"; | |||||
| }else | |||||
| return "bad"; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,82 @@ | |||||
| package Unreleased_DB_Resource; | |||||
| import java.sql.Connection; | |||||
| import java.sql.PreparedStatement; | |||||
| import java.sql.ResultSet; | |||||
| import java.sql.SQLException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| public class Unreleased_DB_Resource { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response,Connection conn) | |||||
| { | |||||
| PreparedStatement statement = null; | |||||
| ResultSet rs = null; | |||||
| try { | |||||
| statement = conn.prepareStatement("select name from users where name = 'lily'"); // bad 数据库资源未释放 | |||||
| rs = statement.executeQuery(); | |||||
| rs.close(); | |||||
| } catch (SQLException e1) { | |||||
| log.info("SQLException"); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response,Connection conn) | |||||
| { | |||||
| PreparedStatement statement = null; | |||||
| ResultSet rs = null; | |||||
| try { | |||||
| statement = conn.prepareStatement("select name from users where name = 'lily'"); // good 数据库资源未释放 | |||||
| rs = statement.executeQuery(); | |||||
| } catch (SQLException e1) { | |||||
| log.info("SQLException"); | |||||
| }finally { | |||||
| try { | |||||
| if( rs != null ) | |||||
| { | |||||
| rs.close(); | |||||
| } | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| try { | |||||
| if( statement != null ) | |||||
| { | |||||
| statement.close(); | |||||
| } | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| try { | |||||
| if( conn != null ) | |||||
| { | |||||
| conn.close(); | |||||
| } | |||||
| } catch (SQLException se) { | |||||
| log.info("Error closing conn"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,106 @@ | |||||
| package Unreleased_Stream; | |||||
| import java.io.BufferedReader; | |||||
| import java.io.File; | |||||
| import java.io.FileReader; | |||||
| import java.io.IOException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| public class Unreleased_Stream { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| int b = 0; /* init data */ | |||||
| int length = 256; | |||||
| File f = new File("C:" + File.separator + "data.txt"); | |||||
| BufferedReader buffread = null; | |||||
| char [] a = null; | |||||
| try { | |||||
| /* read string from file into data */ | |||||
| buffread = new BufferedReader(new FileReader(f)); // bad 流资源未释放 | |||||
| if(buffread.read() < length){ | |||||
| b = buffread.read(a, 0, length); | |||||
| } | |||||
| log.info(b + ""); | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| log.info("Error with stream reading"); | |||||
| } | |||||
| catch( NumberFormatException nfe ) | |||||
| { | |||||
| log.info("Error with number parsing"); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| int b = 0; /* init data */ | |||||
| int length = 256; | |||||
| File f = new File("C:" + File.separator + "data.txt"); | |||||
| BufferedReader buffread = null; | |||||
| FileReader fread = null; | |||||
| char [] a = null; | |||||
| try { | |||||
| /* read string from file into data */ | |||||
| fread = new FileReader(f); | |||||
| buffread = new BufferedReader(fread); // good 流资源未释放 | |||||
| if(buffread.read() < length){ | |||||
| b = buffread.read(a, 0, length); | |||||
| } | |||||
| log.info(b + ""); | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| log.info("Error with stream reading"); | |||||
| } | |||||
| catch( NumberFormatException nfe ) | |||||
| { | |||||
| log.info("Error with number parsing"); | |||||
| } | |||||
| finally { | |||||
| /* clean up stream reading objects */ | |||||
| try { | |||||
| if( buffread != null ) | |||||
| { | |||||
| buffread.close(); | |||||
| } | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| log.info("Error closing buffread"); | |||||
| } | |||||
| finally { | |||||
| try { | |||||
| if( fread != null ) | |||||
| { | |||||
| fread.close(); | |||||
| } | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| log.info("Error closing fread"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package Unsafe_Hash_Algorithm; | |||||
| import javax.servlet.http.*; | |||||
| import java.security.MessageDigest; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| import java.util.logging.Logger; | |||||
| public class Unsafe_Hash_Algorithm | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| String data = "admin:12345"; | |||||
| String secretHash = "my_secret_seed"; | |||||
| MessageDigest hash = null; | |||||
| try { | |||||
| hash = MessageDigest.getInstance("SHA1"); // bad 不安全的哈希算法 | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| /* FIX: plaintext credentials hashed with salt prior to setting in cookie */ | |||||
| if(hash != null){ | |||||
| byte[] hashv = hash.digest((secretHash + data).getBytes()); | |||||
| log.info(hashv + ""); | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request, HttpServletResponse response) | |||||
| { | |||||
| String data = "admin:12345"; | |||||
| String secretHash = "my_secret_seed"; | |||||
| MessageDigest hash = null; | |||||
| try { | |||||
| hash = MessageDigest.getInstance("SHA-256"); // good 不安全的哈希算法 | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| /* FIX: plaintext credentials hashed with salt prior to setting in cookie */ | |||||
| if(hash != null){ | |||||
| byte[] hashv = hash.digest((secretHash + data).getBytes()); | |||||
| log.info(hashv + ""); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,67 @@ | |||||
| package Unsafe_Reflection; | |||||
| import java.util.logging.Logger; | |||||
| public class Unsafe_Reflection | |||||
| { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public void bad() | |||||
| { | |||||
| String data = System.getProperty("ADD"); | |||||
| if(data != null){ | |||||
| Class<?> c = null; | |||||
| try { | |||||
| c = Class.forName(data); // bad 不安全的反射 | |||||
| } catch (ClassNotFoundException e) { | |||||
| log.info("error"); | |||||
| } /* FLAW: loading arbitrary class */ | |||||
| Object instance = null; | |||||
| try { | |||||
| if(c != null){ | |||||
| instance = c.newInstance(); | |||||
| log.info(instance.toString()); | |||||
| } | |||||
| } catch (InstantiationException e) { | |||||
| log.info("error"); | |||||
| } catch (IllegalAccessException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| } | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| String data = System.getProperty("ADD"); | |||||
| if (data!=null && !data.equals("Testing.test") && /* FIX: classname must be one of 2 values */ | |||||
| !data.equals("Test.test")) | |||||
| { | |||||
| return; | |||||
| } | |||||
| Class<?> c = null; | |||||
| try { | |||||
| c = Class.forName(data); // good 不安全的反射 | |||||
| } catch (ClassNotFoundException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| Object instance = null; | |||||
| try { | |||||
| if(c != null){ | |||||
| instance = c.newInstance(); | |||||
| log.info(instance.toString()); | |||||
| } | |||||
| } catch (InstantiationException e) { | |||||
| log.info("error"); | |||||
| } catch (IllegalAccessException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package Unused_Filed; | |||||
| import java.util.logging.Logger; | |||||
| public class Unused_Filed { | |||||
| private String b = "test"; // bad 未使用的字段 | |||||
| private String a = "used"; // good 未使用的字段 | |||||
| public void good() { | |||||
| Logger log = Logger.getLogger("log"); | |||||
| log.info(a); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| package Unused_Method; | |||||
| public class Unused_Method | |||||
| { | |||||
| private String bad() // bad 未使用的方法 | |||||
| { | |||||
| return "Calculation"; | |||||
| } | |||||
| /* FIX: good() method calls calculation() */ | |||||
| private String calculation() // good 未使用的方法 | |||||
| { | |||||
| return "Calculation"; | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| calculation(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| package Unused_Variable; | |||||
| import java.util.logging.Logger; | |||||
| public class Unused_Variable | |||||
| { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| /* use badsource and badsink */ | |||||
| public void bad() | |||||
| { | |||||
| Integer data; | |||||
| /* POTENTIAL FLAW: Initialize, but do not use data */ | |||||
| data = 5; // bad 变量赋值后未使用 | |||||
| } | |||||
| public void good() | |||||
| { | |||||
| Integer data; | |||||
| /* POTENTIAL FLAW: Initialize, but do not use data */ | |||||
| data = 5; // good 变量赋值后未使用 | |||||
| /* FIX: Use data */ | |||||
| log.info("" + data); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,102 @@ | |||||
| package Use_Float_For_Compute; | |||||
| import java.math.BigDecimal; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| public class Use_Float_For_Compute { | |||||
| public static String bad(String txt) { | |||||
| if (StringUtils.isBlank(txt)) { | |||||
| return txt; | |||||
| } | |||||
| StringBuilder sb = new StringBuilder((int) (txt.length() * 1.2)); // bad 浣跨敤娴偣鏁拌繘琛岀簿纭绠� | |||||
| char c; | |||||
| boolean doub = false; | |||||
| for (int i = 0; i < txt.length(); i++) { | |||||
| c = txt.charAt(i); | |||||
| if (c == ' ') { | |||||
| if (doub) { | |||||
| sb.append(' '); | |||||
| doub = false; | |||||
| } else { | |||||
| sb.append(" "); | |||||
| doub = true; | |||||
| } | |||||
| } else { | |||||
| doub = false; | |||||
| switch (c) { | |||||
| case '&': | |||||
| sb.append("&"); | |||||
| break; | |||||
| case '<': | |||||
| sb.append("<"); | |||||
| break; | |||||
| case '>': | |||||
| sb.append(">"); | |||||
| break; | |||||
| case '"': | |||||
| sb.append("""); | |||||
| break; | |||||
| case '\n': | |||||
| sb.append("<br/>"); | |||||
| break; | |||||
| default: | |||||
| sb.append(c); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| return sb.toString(); | |||||
| } | |||||
| public static String good(String txt) { | |||||
| if (StringUtils.isBlank(txt)) { | |||||
| return txt; | |||||
| } | |||||
| BigDecimal b1 = new BigDecimal(1.2); | |||||
| BigDecimal b2 = new BigDecimal(txt.length()); | |||||
| BigDecimal b3 = b1.multiply(b2); | |||||
| StringBuilder sb = new StringBuilder( b3 + ""); // good 浣跨敤娴偣鏁拌繘琛岀簿纭绠� | |||||
| char c; | |||||
| boolean doub = false; | |||||
| for (int i = 0; i < txt.length(); i++) { | |||||
| c = txt.charAt(i); | |||||
| if (c == ' ') { | |||||
| if (doub) { | |||||
| sb.append(' '); | |||||
| doub = false; | |||||
| } else { | |||||
| sb.append(" "); | |||||
| doub = true; | |||||
| } | |||||
| } else { | |||||
| doub = false; | |||||
| switch (c) { | |||||
| case '&': | |||||
| sb.append("&"); | |||||
| break; | |||||
| case '<': | |||||
| sb.append("<"); | |||||
| break; | |||||
| case '>': | |||||
| sb.append(">"); | |||||
| break; | |||||
| case '"': | |||||
| sb.append("""); | |||||
| break; | |||||
| case '\n': | |||||
| sb.append("<br/>"); | |||||
| break; | |||||
| default: | |||||
| sb.append(c); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| return sb.toString(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,86 @@ | |||||
| package Weak_Encryption; | |||||
| import java.security.InvalidKeyException; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| import java.util.logging.Logger; | |||||
| import javax.crypto.BadPaddingException; | |||||
| import javax.crypto.Cipher; | |||||
| import javax.crypto.IllegalBlockSizeException; | |||||
| import javax.crypto.NoSuchPaddingException; | |||||
| import javax.crypto.spec.SecretKeySpec; | |||||
| public class Weak_Encryption { | |||||
| static final Logger log = Logger.getLogger("local-logger"); | |||||
| public String bad() | |||||
| { | |||||
| String data = "root"; /* init data */ | |||||
| String sKey = "sKey"; | |||||
| Cipher cipher = null; | |||||
| try { | |||||
| SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "DES"); | |||||
| cipher = Cipher.getInstance("DES"); // bad 寮卞姞瀵� | |||||
| cipher.init(Cipher.DECRYPT_MODE, key); | |||||
| } catch (NoSuchPaddingException e) { | |||||
| log.info("error"); | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } catch (InvalidKeyException e) { | |||||
| log.info("InvalidKeyException"); | |||||
| } | |||||
| String pw = ""; | |||||
| try { | |||||
| if(cipher != null){ | |||||
| pw = new String(cipher.doFinal(data.getBytes())); | |||||
| } | |||||
| } catch (IllegalBlockSizeException e) { | |||||
| log.info("error"); | |||||
| } catch (BadPaddingException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| String cipertext = pw; | |||||
| return cipertext; | |||||
| } | |||||
| public String good() | |||||
| { | |||||
| String data = "root"; /* init data */ | |||||
| String sKey = "sKey"; | |||||
| Cipher cipher = null; | |||||
| try { | |||||
| SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "AES"); | |||||
| cipher = Cipher.getInstance("AES"); // good 寮卞姞瀵� | |||||
| cipher.init(Cipher.DECRYPT_MODE, key); | |||||
| } catch ( NoSuchPaddingException e) { | |||||
| log.info("error"); | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| log.info("error"); | |||||
| } catch (InvalidKeyException e) { | |||||
| log.info("InvalidKeyException"); | |||||
| } | |||||
| String pw = ""; | |||||
| try { | |||||
| if(cipher != null){ | |||||
| pw = new String(cipher.doFinal(data.getBytes())); | |||||
| } | |||||
| } catch (IllegalBlockSizeException e) { | |||||
| log.info("error"); | |||||
| } catch (BadPaddingException e) { | |||||
| log.info("error"); | |||||
| } | |||||
| String cipertext = pw; | |||||
| return cipertext; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,88 @@ | |||||
| package XPath_Injection; | |||||
| import java.io.File; | |||||
| import java.io.FileInputStream; | |||||
| import java.io.FileNotFoundException; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.util.logging.Logger; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.xml.xpath.XPath; | |||||
| import javax.xml.xpath.XPathConstants; | |||||
| import javax.xml.xpath.XPathExpressionException; | |||||
| import javax.xml.xpath.XPathFactory; | |||||
| import org.w3c.dom.NodeList; | |||||
| import org.xml.sax.InputSource; | |||||
| public class XPath_Injection { | |||||
| static final Logger log = Logger.getLogger("logger"); | |||||
| public void bad(HttpServletRequest request) throws XPathExpressionException { | |||||
| String username = request.getParameter("name"); | |||||
| String dir = "C:" + File.separator + "EmployeesData.xml"; | |||||
| File d = new File(dir); | |||||
| XPathFactory factory = XPathFactory.newInstance(); | |||||
| XPath xPath = factory.newXPath(); | |||||
| NodeList nodes = null; | |||||
| InputStream in = null; | |||||
| InputSource inputSource = null; | |||||
| try { | |||||
| in = new FileInputStream(d); | |||||
| inputSource = new InputSource(in); | |||||
| String expression = "/employees/employee[loginID/text()='" | |||||
| + username + "']"; | |||||
| nodes = (NodeList) xPath.evaluate(expression, inputSource, XPathConstants.NODESET); // bad XPath注入 | |||||
| log.info(nodes.item(1).getLocalName()); | |||||
| } catch (FileNotFoundException e) { | |||||
| log.info("FileNotFoundException"); | |||||
| } finally { | |||||
| try { | |||||
| if(in!=null){ | |||||
| in.close(); | |||||
| } | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| public void good(HttpServletRequest request) | |||||
| throws XPathExpressionException { | |||||
| String username = "foo"; | |||||
| String dir = "C:" + File.separator + "EmployeesData.xml"; | |||||
| File d = new File(dir); | |||||
| XPathFactory factory = XPathFactory.newInstance(); | |||||
| XPath xPath = factory.newXPath(); | |||||
| NodeList nodes = null; | |||||
| InputStream in = null; | |||||
| InputSource inputSource = null; | |||||
| try { | |||||
| in = new FileInputStream(d); | |||||
| inputSource = new InputSource(in); | |||||
| String expression = "/employees/employee[loginID/text()='" | |||||
| + username + "']"; | |||||
| nodes = (NodeList) xPath.evaluate(expression, inputSource, XPathConstants.NODESET); // good XPath注入 | |||||
| log.info(nodes.item(1).getLocalName()); | |||||
| } catch (FileNotFoundException e) { | |||||
| log.info("FileNotFoundException"); | |||||
| } finally { | |||||
| try { | |||||
| if(in!=null){ | |||||
| in.close(); | |||||
| } | |||||
| } catch (IOException e) { | |||||
| log.info("IOException"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||