| @@ -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"); | |||
| } | |||
| } | |||
| } | |||
| } | |||