From dc5ef56004394bf4a1c69808836c379969354e84 Mon Sep 17 00:00:00 2001 From: weishao Date: Fri, 10 Mar 2023 16:08:36 +0800 Subject: [PATCH] init --- .DS_Store | Bin 0 -> 6148 bytes Command_Injection/Command_Injection.java | 56 ++++++++ .../Create_Boolean_Object.java | 18 +++ .../Create_String_Object.java | 19 +++ Debug_Code/Debug_Code_bad.java | 21 +++ Debug_Code/Debug_Code_good.java | 21 +++ Empty_Catch_Block/Empty_Catch_Block.java | 31 +++++ Empty_If_Block/Empty_If_Block.java | 23 ++++ Empty_Password/Empty_Password.java | 19 +++ .../Empty_String_Compare.java | 25 ++++ Empty_Syn_Block/Empty_Syn_Block.java | 28 ++++ .../Expression_Always_False_01.java | 35 +++++ .../Expression_Always_False_02.java | 35 +++++ .../Expression_Always_True_01.java | 37 +++++ .../Expression_Always_True_02.java | 38 ++++++ HTML_Comment_in_JSP/HTML_Comment_in_JSP.jsp | 13 ++ .../HTTP_Response_Splitting.java | 27 ++++ Hard_Coded_Password/Hard_Coded_Password.java | 65 +++++++++ .../Insecuere_Randomness.java | 41 ++++++ ...ctices_Use_of_System_Exit__Servlet_01.java | 34 +++++ ...one_of_Equals_or_hashCode_defined_bad.java | 22 +++ ...ne_of_Equals_or_hashCode_defined_good.java | 26 ++++ LDAP_Injection/LDAP_Injection.java | 55 ++++++++ Log_Forging/Log_Forging.java | 48 +++++++ .../Logging_using_System_output.java | 20 +++ Null_Password/Null_Password.java | 60 +++++++++ Obsolete_Method/Obsolete_Method.java | 17 +++ Open_Redirect/Open_Redirect_bad.jsp | 6 + Open_Redirect/Open_Redirect_good.jsp | 8 ++ Overly_board_Catch/Overly_board_Catch.java | 41 ++++++ Overly_board_Throws/Overly_board_Throws.java | 33 +++++ Path_Manipulate/Path_Manipulate.java | 23 ++++ Persist_XSS/Persist_XSS.java | 85 ++++++++++++ .../Redundence_Initialize.java | 27 ++++ Reflect_XSS/Reflect_XSS_bad.jsp | 19 +++ Reflect_XSS/Reflect_XSS_good.jsp | 20 +++ Return_in_Finally/Return_in_Finally.java | 51 +++++++ SQL_Injection/SQL_Injection.java | 126 ++++++++++++++++++ .../Static_Field_Not_Final.java | 14 ++ .../String_Compare_Error.java | 24 ++++ Stringbuild_in_loop/Stringbuild_in_loop.java | 26 ++++ .../System_Information_Leak.java | 44 ++++++ .../Throws_Excepiton_in_Finally.java | 44 ++++++ .../Trust_Boundary_Violation.java | 38 ++++++ .../Unchecked_Return_Value.java | 27 ++++ .../Unreleased_DB_Resource.java | 82 ++++++++++++ Unreleased_Stream/Unreleased_Stream.java | 106 +++++++++++++++ .../Unsafe_Hash_Algorithm.java | 54 ++++++++ Unsafe_Reflection/Unsafe_Reflection.java | 67 ++++++++++ Unused_Filed/Unused_Filed.java | 17 +++ Unused_Method/Unused_Method.java | 22 +++ Unused_Variable/Unused_Variable.java | 33 +++++ .../Use_Float_For_Compute.java | 102 ++++++++++++++ Weak_Encryption/Weak_Encryption.java | 86 ++++++++++++ XPath_Injection/XPath_Injection.java | 88 ++++++++++++ 55 files changed, 2147 insertions(+) create mode 100644 .DS_Store create mode 100644 Command_Injection/Command_Injection.java create mode 100644 Create_Boolean_Object/Create_Boolean_Object.java create mode 100644 Create_String_Object/Create_String_Object.java create mode 100644 Debug_Code/Debug_Code_bad.java create mode 100644 Debug_Code/Debug_Code_good.java create mode 100644 Empty_Catch_Block/Empty_Catch_Block.java create mode 100644 Empty_If_Block/Empty_If_Block.java create mode 100644 Empty_Password/Empty_Password.java create mode 100644 Empty_String_Compare/Empty_String_Compare.java create mode 100644 Empty_Syn_Block/Empty_Syn_Block.java create mode 100644 Expression_Always_False/Expression_Always_False_01.java create mode 100644 Expression_Always_False/Expression_Always_False_02.java create mode 100644 Expression_Always_True/Expression_Always_True_01.java create mode 100644 Expression_Always_True/Expression_Always_True_02.java create mode 100644 HTML_Comment_in_JSP/HTML_Comment_in_JSP.jsp create mode 100644 HTTP_Response_Splitting/HTTP_Response_Splitting.java create mode 100644 Hard_Coded_Password/Hard_Coded_Password.java create mode 100644 Insecuere_Randomness/Insecuere_Randomness.java create mode 100644 J2EE_Bad_Practices_Use_of_System_Exit/J2EE_Bad_Practices_Use_of_System_Exit__Servlet_01.java create mode 100644 Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_bad.java create mode 100644 Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_good.java create mode 100644 LDAP_Injection/LDAP_Injection.java create mode 100644 Log_Forging/Log_Forging.java create mode 100644 Logging_using_System_output/Logging_using_System_output.java create mode 100644 Null_Password/Null_Password.java create mode 100644 Obsolete_Method/Obsolete_Method.java create mode 100644 Open_Redirect/Open_Redirect_bad.jsp create mode 100644 Open_Redirect/Open_Redirect_good.jsp create mode 100644 Overly_board_Catch/Overly_board_Catch.java create mode 100644 Overly_board_Throws/Overly_board_Throws.java create mode 100644 Path_Manipulate/Path_Manipulate.java create mode 100644 Persist_XSS/Persist_XSS.java create mode 100644 Redundence_Initialize/Redundence_Initialize.java create mode 100644 Reflect_XSS/Reflect_XSS_bad.jsp create mode 100644 Reflect_XSS/Reflect_XSS_good.jsp create mode 100644 Return_in_Finally/Return_in_Finally.java create mode 100644 SQL_Injection/SQL_Injection.java create mode 100644 Static_Field_Not_Final/Static_Field_Not_Final.java create mode 100644 String_Compare_Error/String_Compare_Error.java create mode 100644 Stringbuild_in_loop/Stringbuild_in_loop.java create mode 100644 System_Information_Leak/System_Information_Leak.java create mode 100644 Throws_Excepiton_in_Finally/Throws_Excepiton_in_Finally.java create mode 100644 Trust_Boundary_Violation/Trust_Boundary_Violation.java create mode 100644 Unchecked_Return_Value/Unchecked_Return_Value.java create mode 100644 Unreleased_DB_Resource/Unreleased_DB_Resource.java create mode 100644 Unreleased_Stream/Unreleased_Stream.java create mode 100644 Unsafe_Hash_Algorithm/Unsafe_Hash_Algorithm.java create mode 100644 Unsafe_Reflection/Unsafe_Reflection.java create mode 100644 Unused_Filed/Unused_Filed.java create mode 100644 Unused_Method/Unused_Method.java create mode 100644 Unused_Variable/Unused_Variable.java create mode 100644 Use_Float_For_Compute/Use_Float_For_Compute.java create mode 100644 Weak_Encryption/Weak_Encryption.java create mode 100644 XPath_Injection/XPath_Injection.java diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..92690173c856fc6a0c7eb7673a4385aa9a2c9bff GIT binary patch literal 6148 zcmeHKyGjF55Iv(Q0uo4Rd4It_SVAlW8_5SKCKgJ_7SVpIe3zf*nFqqMv9Pd_Gca@R zot?9ndy1VM0Ji$r-2h7fbGjo=9;W8c-6wWY86(p9jyoLih8Jw{KB+#RaP9&dJm4OW zBmOIT9CpX;{<-h>=gG=S0VyB_q<|EV0>4(kdoOK%m8d8Mq<|FoR=~dxjqcbL4vF#U zV2BZbIAc1D>zE~o%@f3~a7bi^W=SO`)oR4Bq%+^Dt}7f8lMbul!|G(K3B}@czQ08| ztV>js0#abCz-4Zi-v4juKg|DQl6F!+3j8YtY_{I4SG-d7*2(3(*EaeS-D^JSZd?b2 nA=)u9+A%lYj<2IA>zc3myek|MgU)==iTW9EU1U<=uNC+LL!}lx literal 0 HcmV?d00001 diff --git a/Command_Injection/Command_Injection.java b/Command_Injection/Command_Injection.java new file mode 100644 index 0000000..b5c54d0 --- /dev/null +++ b/Command_Injection/Command_Injection.java @@ -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"; + } + } + +} + diff --git a/Create_Boolean_Object/Create_Boolean_Object.java b/Create_Boolean_Object/Create_Boolean_Object.java new file mode 100644 index 0000000..ab88207 --- /dev/null +++ b/Create_Boolean_Object/Create_Boolean_Object.java @@ -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); + } +} diff --git a/Create_String_Object/Create_String_Object.java b/Create_String_Object/Create_String_Object.java new file mode 100644 index 0000000..82bbb0a --- /dev/null +++ b/Create_String_Object/Create_String_Object.java @@ -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); + } + +} diff --git a/Debug_Code/Debug_Code_bad.java b/Debug_Code/Debug_Code_bad.java new file mode 100644 index 0000000..326563c --- /dev/null +++ b/Debug_Code/Debug_Code_bad.java @@ -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"); + } + + +} diff --git a/Debug_Code/Debug_Code_good.java b/Debug_Code/Debug_Code_good.java new file mode 100644 index 0000000..2fbe524 --- /dev/null +++ b/Debug_Code/Debug_Code_good.java @@ -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"); +// } + + +} diff --git a/Empty_Catch_Block/Empty_Catch_Block.java b/Empty_Catch_Block/Empty_Catch_Block.java new file mode 100644 index 0000000..47b71f9 --- /dev/null +++ b/Empty_Catch_Block/Empty_Catch_Block.java @@ -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"); + } + } + +} diff --git a/Empty_If_Block/Empty_If_Block.java b/Empty_If_Block/Empty_If_Block.java new file mode 100644 index 0000000..6db7ea6 --- /dev/null +++ b/Empty_If_Block/Empty_If_Block.java @@ -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; + } + + } +} diff --git a/Empty_Password/Empty_Password.java b/Empty_Password/Empty_Password.java new file mode 100644 index 0000000..89d6596 --- /dev/null +++ b/Empty_Password/Empty_Password.java @@ -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 ""; + } + +} \ No newline at end of file diff --git a/Empty_String_Compare/Empty_String_Compare.java b/Empty_String_Compare/Empty_String_Compare.java new file mode 100644 index 0000000..4d4d225 --- /dev/null +++ b/Empty_String_Compare/Empty_String_Compare.java @@ -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; + } + + } + +} diff --git a/Empty_Syn_Block/Empty_Syn_Block.java b/Empty_Syn_Block/Empty_Syn_Block.java new file mode 100644 index 0000000..9e35668 --- /dev/null +++ b/Empty_Syn_Block/Empty_Syn_Block.java @@ -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"); + } + } + +} diff --git a/Expression_Always_False/Expression_Always_False_01.java b/Expression_Always_False/Expression_Always_False_01.java new file mode 100644 index 0000000..ba71c10 --- /dev/null +++ b/Expression_Always_False/Expression_Always_False_01.java @@ -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"); + } + } + +} diff --git a/Expression_Always_False/Expression_Always_False_02.java b/Expression_Always_False/Expression_Always_False_02.java new file mode 100644 index 0000000..1307758 --- /dev/null +++ b/Expression_Always_False/Expression_Always_False_02.java @@ -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"); + } + } + +} diff --git a/Expression_Always_True/Expression_Always_True_01.java b/Expression_Always_True/Expression_Always_True_01.java new file mode 100644 index 0000000..2c5bb93 --- /dev/null +++ b/Expression_Always_True/Expression_Always_True_01.java @@ -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"); + } + } + +} diff --git a/Expression_Always_True/Expression_Always_True_02.java b/Expression_Always_True/Expression_Always_True_02.java new file mode 100644 index 0000000..ea2ed99 --- /dev/null +++ b/Expression_Always_True/Expression_Always_True_02.java @@ -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"); + } + } + +} diff --git a/HTML_Comment_in_JSP/HTML_Comment_in_JSP.jsp b/HTML_Comment_in_JSP/HTML_Comment_in_JSP.jsp new file mode 100644 index 0000000..aa87321 --- /dev/null +++ b/HTML_Comment_in_JSP/HTML_Comment_in_JSP.jsp @@ -0,0 +1,13 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + + +HTTP Splitting + + + <% response.sendRedirect("https://aa.com/test.php"); %> <%-- // good HTML Comment in JSP file --%> + <%-- // bad HTML Comment in JSP file --%> + + \ No newline at end of file diff --git a/HTTP_Response_Splitting/HTTP_Response_Splitting.java b/HTTP_Response_Splitting/HTTP_Response_Splitting.java new file mode 100644 index 0000000..b3bbeeb --- /dev/null +++ b/HTTP_Response_Splitting/HTTP_Response_Splitting.java @@ -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响应截断 + + } + + +} diff --git a/Hard_Coded_Password/Hard_Coded_Password.java b/Hard_Coded_Password/Hard_Coded_Password.java new file mode 100644 index 0000000..25d1518 --- /dev/null +++ b/Hard_Coded_Password/Hard_Coded_Password.java @@ -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; + + } + +} + diff --git a/Insecuere_Randomness/Insecuere_Randomness.java b/Insecuere_Randomness/Insecuere_Randomness.java new file mode 100644 index 0000000..9649a01 --- /dev/null +++ b/Insecuere_Randomness/Insecuere_Randomness.java @@ -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"); + } + + + } + + +} + diff --git a/J2EE_Bad_Practices_Use_of_System_Exit/J2EE_Bad_Practices_Use_of_System_Exit__Servlet_01.java b/J2EE_Bad_Practices_Use_of_System_Exit/J2EE_Bad_Practices_Use_of_System_Exit__Servlet_01.java new file mode 100644 index 0000000..a49a710 --- /dev/null +++ b/J2EE_Bad_Practices_Use_of_System_Exit/J2EE_Bad_Practices_Use_of_System_Exit__Servlet_01.java @@ -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()关闭应用程序容器 + + } + + +} + diff --git a/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_bad.java b/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_bad.java new file mode 100644 index 0000000..983a4a0 --- /dev/null +++ b/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_bad.java @@ -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; + + } + +} diff --git a/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_good.java b/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_good.java new file mode 100644 index 0000000..2f779f1 --- /dev/null +++ b/Just_one_of_Equals_or_hashCode_defined/Just_one_of_Equals_or_hashCode_defined_good.java @@ -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; + + } + +} diff --git a/LDAP_Injection/LDAP_Injection.java b/LDAP_Injection/LDAP_Injection.java new file mode 100644 index 0000000..aca18cf --- /dev/null +++ b/LDAP_Injection/LDAP_Injection.java @@ -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 env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, "ldap://localhost:389"); + DirContext ctx = new InitialDirContext(env); + + String search = "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */ + + NamingEnumeration answer = ctx.search("", search, null); // bad LDAP注入 + if (answer.hasMore()) + { + log.info("ok"); + } + + } + + + public void good(HttpServletRequest request, HttpServletResponse response) throws NamingException, IOException + { + String data = "foo"; + + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, "ldap://localhost:389"); + DirContext ctx = new InitialDirContext(env); + + String search = "(cn=" + data + ")"; /* POTENTIAL FLAW: unsanitized data from untrusted source */ + + NamingEnumeration answer = ctx.search("", search, null); // good LDAP注入 + if (answer.hasMore()) + { + log.info("ok"); + } + + } +} + diff --git a/Log_Forging/Log_Forging.java b/Log_Forging/Log_Forging.java new file mode 100644 index 0000000..d4a628b --- /dev/null +++ b/Log_Forging/Log_Forging.java @@ -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 日志伪造 + } + + } + + + + +} diff --git a/Logging_using_System_output/Logging_using_System_output.java b/Logging_using_System_output/Logging_using_System_output.java new file mode 100644 index 0000000..995b823 --- /dev/null +++ b/Logging_using_System_output/Logging_using_System_output.java @@ -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 系统输出流记录日志 + } + +} diff --git a/Null_Password/Null_Password.java b/Null_Password/Null_Password.java new file mode 100644 index 0000000..eb24c8e --- /dev/null +++ b/Null_Password/Null_Password.java @@ -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; + + } + +} diff --git a/Obsolete_Method/Obsolete_Method.java b/Obsolete_Method/Obsolete_Method.java new file mode 100644 index 0000000..ae273fa --- /dev/null +++ b/Obsolete_Method/Obsolete_Method.java @@ -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; + } + +} diff --git a/Open_Redirect/Open_Redirect_bad.jsp b/Open_Redirect/Open_Redirect_bad.jsp new file mode 100644 index 0000000..d56b8b9 --- /dev/null +++ b/Open_Redirect/Open_Redirect_bad.jsp @@ -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 --%> \ No newline at end of file diff --git a/Open_Redirect/Open_Redirect_good.jsp b/Open_Redirect/Open_Redirect_good.jsp new file mode 100644 index 0000000..7685d25 --- /dev/null +++ b/Open_Redirect/Open_Redirect_good.jsp @@ -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 --%> \ No newline at end of file diff --git a/Overly_board_Catch/Overly_board_Catch.java b/Overly_board_Catch/Overly_board_Catch.java new file mode 100644 index 0000000..58a3714 --- /dev/null +++ b/Overly_board_Catch/Overly_board_Catch.java @@ -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"); + } + + } + +} diff --git a/Overly_board_Throws/Overly_board_Throws.java b/Overly_board_Throws/Overly_board_Throws.java new file mode 100644 index 0000000..48a4b97 --- /dev/null +++ b/Overly_board_Throws/Overly_board_Throws.java @@ -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"); + } + + + } + +} diff --git a/Path_Manipulate/Path_Manipulate.java b/Path_Manipulate/Path_Manipulate.java new file mode 100644 index 0000000..d7da9ab --- /dev/null +++ b/Path_Manipulate/Path_Manipulate.java @@ -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(); + } + + +} diff --git a/Persist_XSS/Persist_XSS.java b/Persist_XSS/Persist_XSS.java new file mode 100644 index 0000000..042e64f --- /dev/null +++ b/Persist_XSS/Persist_XSS.java @@ -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("
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("
bad() - Parameter name has value " + data); // good 存储型XSS + } catch (IOException e) { + log.info("IOException"); + } + + + } + + +} + diff --git a/Redundence_Initialize/Redundence_Initialize.java b/Redundence_Initialize/Redundence_Initialize.java new file mode 100644 index 0000000..b62e4bf --- /dev/null +++ b/Redundence_Initialize/Redundence_Initialize.java @@ -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); + } + +} diff --git a/Reflect_XSS/Reflect_XSS_bad.jsp b/Reflect_XSS/Reflect_XSS_bad.jsp new file mode 100644 index 0000000..56e0f7a --- /dev/null +++ b/Reflect_XSS/Reflect_XSS_bad.jsp @@ -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 + } + +} +%> \ No newline at end of file diff --git a/Reflect_XSS/Reflect_XSS_good.jsp b/Reflect_XSS/Reflect_XSS_good.jsp new file mode 100644 index 0000000..c6e621d --- /dev/null +++ b/Reflect_XSS/Reflect_XSS_good.jsp @@ -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 + + } + +} +%> \ No newline at end of file diff --git a/Return_in_Finally/Return_in_Finally.java b/Return_in_Finally/Return_in_Finally.java new file mode 100644 index 0000000..57c76bc --- /dev/null +++ b/Return_in_Finally/Return_in_Finally.java @@ -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语句 + } + + } + +} + diff --git a/SQL_Injection/SQL_Injection.java b/SQL_Injection/SQL_Injection.java new file mode 100644 index 0000000..32ddaca --- /dev/null +++ b/SQL_Injection/SQL_Injection.java @@ -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"); + } + } + } + + } + +} + diff --git a/Static_Field_Not_Final/Static_Field_Not_Final.java b/Static_Field_Not_Final/Static_Field_Not_Final.java new file mode 100644 index 0000000..0a01c60 --- /dev/null +++ b/Static_Field_Not_Final/Static_Field_Not_Final.java @@ -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() { } + + +} diff --git a/String_Compare_Error/String_Compare_Error.java b/String_Compare_Error/String_Compare_Error.java new file mode 100644 index 0000000..2557e3e --- /dev/null +++ b/String_Compare_Error/String_Compare_Error.java @@ -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"; + } + + } + +} diff --git a/Stringbuild_in_loop/Stringbuild_in_loop.java b/Stringbuild_in_loop/Stringbuild_in_loop.java new file mode 100644 index 0000000..764048d --- /dev/null +++ b/Stringbuild_in_loop/Stringbuild_in_loop.java @@ -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 + "
"; // bad 循环中拼接字符串 + } + + } + + public void Stringbuild_in_loop_good() { + + StringBuilder a = new StringBuilder("test"); + + for (int i = 0; i < 5; i++) { + + a.append("
"); // good 循环中拼接字符串 + } + + } + +} diff --git a/System_Information_Leak/System_Information_Leak.java b/System_Information_Leak/System_Information_Leak.java new file mode 100644 index 0000000..54389d3 --- /dev/null +++ b/System_Information_Leak/System_Information_Leak.java @@ -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 系统信息泄露 + } + + } + +} + diff --git a/Throws_Excepiton_in_Finally/Throws_Excepiton_in_Finally.java b/Throws_Excepiton_in_Finally/Throws_Excepiton_in_Finally.java new file mode 100644 index 0000000..564f2db --- /dev/null +++ b/Throws_Excepiton_in_Finally/Throws_Excepiton_in_Finally.java @@ -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"); + } + + } + +} diff --git a/Trust_Boundary_Violation/Trust_Boundary_Violation.java b/Trust_Boundary_Violation/Trust_Boundary_Violation.java new file mode 100644 index 0000000..fa433cc --- /dev/null +++ b/Trust_Boundary_Violation/Trust_Boundary_Violation.java @@ -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"; + } + } + +} diff --git a/Unchecked_Return_Value/Unchecked_Return_Value.java b/Unchecked_Return_Value/Unchecked_Return_Value.java new file mode 100644 index 0000000..96f9c2f --- /dev/null +++ b/Unchecked_Return_Value/Unchecked_Return_Value.java @@ -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"; + } + +} diff --git a/Unreleased_DB_Resource/Unreleased_DB_Resource.java b/Unreleased_DB_Resource/Unreleased_DB_Resource.java new file mode 100644 index 0000000..c7fec7c --- /dev/null +++ b/Unreleased_DB_Resource/Unreleased_DB_Resource.java @@ -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"); + } + + } + + } + + + +} diff --git a/Unreleased_Stream/Unreleased_Stream.java b/Unreleased_Stream/Unreleased_Stream.java new file mode 100644 index 0000000..5d0c11a --- /dev/null +++ b/Unreleased_Stream/Unreleased_Stream.java @@ -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"); + } + } + } + + } + + +} diff --git a/Unsafe_Hash_Algorithm/Unsafe_Hash_Algorithm.java b/Unsafe_Hash_Algorithm/Unsafe_Hash_Algorithm.java new file mode 100644 index 0000000..e4bff35 --- /dev/null +++ b/Unsafe_Hash_Algorithm/Unsafe_Hash_Algorithm.java @@ -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 + ""); + } + } + +} + diff --git a/Unsafe_Reflection/Unsafe_Reflection.java b/Unsafe_Reflection/Unsafe_Reflection.java new file mode 100644 index 0000000..679b513 --- /dev/null +++ b/Unsafe_Reflection/Unsafe_Reflection.java @@ -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"); + } + + } + +} + diff --git a/Unused_Filed/Unused_Filed.java b/Unused_Filed/Unused_Filed.java new file mode 100644 index 0000000..596815c --- /dev/null +++ b/Unused_Filed/Unused_Filed.java @@ -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); + } + +} diff --git a/Unused_Method/Unused_Method.java b/Unused_Method/Unused_Method.java new file mode 100644 index 0000000..b440c3f --- /dev/null +++ b/Unused_Method/Unused_Method.java @@ -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(); + } + +} diff --git a/Unused_Variable/Unused_Variable.java b/Unused_Variable/Unused_Variable.java new file mode 100644 index 0000000..669381e --- /dev/null +++ b/Unused_Variable/Unused_Variable.java @@ -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); + + } + + +} + diff --git a/Use_Float_For_Compute/Use_Float_For_Compute.java b/Use_Float_For_Compute/Use_Float_For_Compute.java new file mode 100644 index 0000000..854ede7 --- /dev/null +++ b/Use_Float_For_Compute/Use_Float_For_Compute.java @@ -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("
"); + 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("
"); + break; + default: + sb.append(c); + break; + } + } + } + return sb.toString(); + } + + +} diff --git a/Weak_Encryption/Weak_Encryption.java b/Weak_Encryption/Weak_Encryption.java new file mode 100644 index 0000000..95c732f --- /dev/null +++ b/Weak_Encryption/Weak_Encryption.java @@ -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; + + } + +} diff --git a/XPath_Injection/XPath_Injection.java b/XPath_Injection/XPath_Injection.java new file mode 100644 index 0000000..aeb7f52 --- /dev/null +++ b/XPath_Injection/XPath_Injection.java @@ -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"); + } + + } + } + +}