From f8b3708e67b0d45f0ca5b102f69448274f38e293 Mon Sep 17 00:00:00 2001 From: tonghuaroot Date: Wed, 22 Sep 2021 07:31:56 +0000 Subject: [PATCH 1/8] Java: BigDecimal DOS --- .../Security/BigDecimalDOS/BigDecimalDOS.java | 28 +++++++++++++ .../BigDecimalDOS/BigDecimalDOS.qhelp | 42 +++++++++++++++++++ .../Security/BigDecimalDOS/BigDecimalDOS.ql | 42 +++++++++++++++++++ .../BigDecimalDOS/BigDecimalDOS.expected | 8 ++++ .../security/BigDecimalDOS/BigDecimalDOS.java | 42 +++++++++++++++++++ .../BigDecimalDOS/BigDecimalDOS.qlref | 1 + .../security/BigDecimalDOS/options | 1 + 7 files changed, 164 insertions(+) create mode 100644 java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.java create mode 100644 java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp create mode 100644 java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql create mode 100644 java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.expected create mode 100644 java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.java create mode 100644 java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.qlref create mode 100644 java/ql/test/experimental/query-tests/security/BigDecimalDOS/options diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.java b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.java new file mode 100644 index 000000000000..066dffb30689 --- /dev/null +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.java @@ -0,0 +1,28 @@ + @GetMapping("/tonghuaroot-DOSDemo01") + @ResponseBody + // BAD: + public Long demo(@RequestParam(name = "num") BigDecimal num) { + Long startTime = System.currentTimeMillis(); + BigDecimal num1 = new BigDecimal(0.005); + System.out.println(num1.add(num)); + Long endTime = System.currentTimeMillis(); + Long tempTime = (endTime - startTime); + System.out.println(tempTime); + return tempTime; + } + + @GetMapping("/tonghuaroot-DOSDemo02") + @ResponseBody + // GOOD: + public Long demo02(@RequestParam(name = "num") String num) { + if (num.length() > 33 || num.matches("(?i)e")) { + return "Input Parameter is too long." + } + Long startTime = System.currentTimeMillis(); + BigDecimal num1 = new BigDecimal(0.005); + System.out.println(num1.add(num)); + Long endTime = System.currentTimeMillis(); + Long tempTime = (endTime - startTime); + System.out.println(tempTime); + return tempTime; + } \ No newline at end of file diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp new file mode 100644 index 000000000000..fa6dff3f731d --- /dev/null +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp @@ -0,0 +1,42 @@ + + + + + +

Directly incorporating user input into an BigDecimal Operation Function without validating the input +can facilitate DOS attacks. In these attacks, the server +will consume a lot of computing resources, A typical scenario is that the CPU usage rises to close to 100%. +This issue often occurs in scenarios that require scientific computing, such as e-commerce platforms and electronic payments. +

+ +
+ + +

To guard against BigDecimal DOS attacks, you should avoid putting user-provided input +directly into a BigDecimal Method(like: add(), subtract()). Instead, In some e-commerce payment scenarios, +we should verify the size of the incoming number. For example, under normal circumstances, +the number representing money will not contain "e".

+ +
+ + +

The following example shows an BigDecimal parameter being used directly pass +to BigDecimal Method(like: add(), subtract()) without validating the input, which facilitates DOS attacks. +It also shows how to remedy the problem by validating the user input against a known fixed string. +

+ + + +
+ +
  • + 暴力的攻击-Dos +
  • +
  • + BigDecimal DOS +
  • + +
    +
    \ No newline at end of file diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql new file mode 100644 index 000000000000..62dec7380215 --- /dev/null +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql @@ -0,0 +1,42 @@ +/** + * @id java/BigDecimalDOS + * @name Java-BigDecimal-DOS-Vulnerability + * @description When user-controllable data is pass to the relevant Methods in BigDecimal, it may cause DOS issues when computing resources are limited. This issue is common in business scenarios such as e-commerce platforms. + * @kind path-problem + * @problem.severity error + */ + +import java +import semmle.code.java.dataflow.FlowSources +import DataFlow::PathGraph + +class BigDecimalDOSConfig extends TaintTracking::Configuration { + BigDecimalDOSConfig() { this = "Java-BigDecimal-DOS-Vulnerability-Config" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + exists(Method method, MethodAccess call | + method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") + and + method.hasName("subtract") + and + call.getMethod() = method and + sink.asExpr() = call.getArgument(0) + ) + or + exists(Method method, MethodAccess call | + method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") + and + method.hasName("add") + and + call.getMethod() = method and + sink.asExpr() = call.getArgument(0) + ) + } +} + +from BigDecimalDOSConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select source.getNode(), source, sink, "Potential Java BigDecimal DOS Issue due to $@.", +source.getNode(), "a user-provided value" \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.expected b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.expected new file mode 100644 index 000000000000..b76c087c107c --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.expected @@ -0,0 +1,8 @@ +edges +| BigDecimalDOS.java:12:28:12:69 | num : BigDecimal | BigDecimalDOS.java:14:30:14:32 | num | +nodes +| BigDecimalDOS.java:12:28:12:69 | num : BigDecimal | semmle.label | num : BigDecimal | +| BigDecimalDOS.java:14:30:14:32 | num | semmle.label | num | +subpaths +#select +| BigDecimalDOS.java:12:28:12:69 | num | BigDecimalDOS.java:12:28:12:69 | num : BigDecimal | BigDecimalDOS.java:14:30:14:32 | num | Potential Java BigDecimal DOS Issue due to $@. | BigDecimalDOS.java:12:28:12:69 | num | a user-provided value | diff --git a/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.java b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.java new file mode 100644 index 000000000000..5deb002c6640 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.java @@ -0,0 +1,42 @@ +package com.example.servingwebcontent; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.math.BigDecimal; +import java.math.MathContext; + +@Controller +public class GreetingController { + @GetMapping("/tonghuaroot-DOSDemo01") + @ResponseBody + // BAD: + public Long demo(@RequestParam(name = "num") BigDecimal num) { + Long startTime = System.currentTimeMillis(); + BigDecimal num1 = new BigDecimal(0.005); + System.out.println(num1.add(num)); + Long endTime = System.currentTimeMillis(); + Long tempTime = (endTime - startTime); + System.out.println(tempTime); + return tempTime; + } + + @GetMapping("/tonghuaroot-DOSDemo02") + @ResponseBody + // GOOD: + public Long demo02(@RequestParam(name = "num") String num) { + if (num.length() > 33 || num.matches("(?i)e")) { + return "Input Parameter is too long." + } + Long startTime = System.currentTimeMillis(); + BigDecimal num1 = new BigDecimal(0.005); + System.out.println(num1.add(num)); + Long endTime = System.currentTimeMillis(); + Long tempTime = (endTime - startTime); + System.out.println(tempTime); + return tempTime; + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.qlref b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.qlref new file mode 100644 index 000000000000..89e06c67483b --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/BigDecimalDOS.qlref @@ -0,0 +1 @@ +experimental/Security/BigDecimalDOS/BigDecimalDOS.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/BigDecimalDOS/options b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/options new file mode 100644 index 000000000000..ba166b547a02 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/BigDecimalDOS/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8/ \ No newline at end of file From 3e21e03bab71084b56939b2d0a3f41ec5df4f3e1 Mon Sep 17 00:00:00 2001 From: tonghuaroot Date: Wed, 22 Sep 2021 07:40:28 +0000 Subject: [PATCH 2/8] format BigDecimalDOS.ql --- .../Security/BigDecimalDOS/BigDecimalDOS.ql | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql index 62dec7380215..42cf3a3e7a0f 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql @@ -11,32 +11,28 @@ import semmle.code.java.dataflow.FlowSources import DataFlow::PathGraph class BigDecimalDOSConfig extends TaintTracking::Configuration { - BigDecimalDOSConfig() { this = "Java-BigDecimal-DOS-Vulnerability-Config" } + BigDecimalDOSConfig() { this = "Java-BigDecimal-DOS-Vulnerability-Config" } override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } override predicate isSink(DataFlow::Node sink) { exists(Method method, MethodAccess call | - method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") - and - method.hasName("subtract") - and + method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") and + method.hasName("subtract") and call.getMethod() = method and sink.asExpr() = call.getArgument(0) ) or exists(Method method, MethodAccess call | - method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") - and - method.hasName("add") - and - call.getMethod() = method and - sink.asExpr() = call.getArgument(0) - ) + method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") and + method.hasName("add") and + call.getMethod() = method and + sink.asExpr() = call.getArgument(0) + ) } } from BigDecimalDOSConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select source.getNode(), source, sink, "Potential Java BigDecimal DOS Issue due to $@.", -source.getNode(), "a user-provided value" \ No newline at end of file + source.getNode(), "a user-provided value" From ca130db2386d0dd4ea571b3c0bfce41e5b2b2bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:41:09 +0800 Subject: [PATCH 3/8] BigDecimalDOS.ql - Adjust the QL code to make it more concise. Co-authored-by: Tony Torralba --- .../experimental/Security/BigDecimalDOS/BigDecimalDOS.ql | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql index 42cf3a3e7a0f..1629871feed0 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql @@ -18,14 +18,7 @@ class BigDecimalDOSConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { exists(Method method, MethodAccess call | method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") and - method.hasName("subtract") and - call.getMethod() = method and - sink.asExpr() = call.getArgument(0) - ) - or - exists(Method method, MethodAccess call | - method.getDeclaringType().hasQualifiedName("java.math", "BigDecimal") and - method.hasName("add") and + method.hasName(["add", "subtract"]) and call.getMethod() = method and sink.asExpr() = call.getArgument(0) ) From dc83252143c0cb8c632b5361b559296b830db60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:44:27 +0800 Subject: [PATCH 4/8] BigDecimalDOS.qhelp - Modify the format of the help document. Co-authored-by: Marcono1234 --- .../src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp index fa6dff3f731d..015ae5f84485 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp @@ -7,7 +7,7 @@

    Directly incorporating user input into an BigDecimal Operation Function without validating the input can facilitate DOS attacks. In these attacks, the server -will consume a lot of computing resources, A typical scenario is that the CPU usage rises to close to 100%. +will consume a lot of computing resources. A typical scenario is that the CPU usage rises to close to 100%. This issue often occurs in scenarios that require scientific computing, such as e-commerce platforms and electronic payments.

    From b6003f54cc184197cf54e1ed1b48d51592832cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:45:36 +0800 Subject: [PATCH 5/8] BigDecimalDOS.qhelp - Modify the format of the help document. Co-authored-by: Marcono1234 --- .../src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp index 015ae5f84485..ba42ff5d5bab 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp @@ -22,7 +22,7 @@ the number representing money will not contain "e".

    -

    The following example shows an BigDecimal parameter being used directly pass +

    The following example shows a BigDecimal parameter being directly passed to BigDecimal Method(like: add(), subtract()) without validating the input, which facilitates DOS attacks. It also shows how to remedy the problem by validating the user input against a known fixed string.

    From 765ed91a2b52e3e4be5d326e8e9b0d560ed24a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:46:05 +0800 Subject: [PATCH 6/8] BigDecimalDOS.qhelp - Modify the format of the help document. Co-authored-by: Marcono1234 --- .../src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp index ba42ff5d5bab..da48c286ffc4 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.qhelp @@ -23,7 +23,7 @@ the number representing money will not contain "e".

    The following example shows a BigDecimal parameter being directly passed -to BigDecimal Method(like: add(), subtract()) without validating the input, which facilitates DOS attacks. +to a BigDecimal method (like: add(), subtract()) without validating the input, which facilitates DOS attacks. It also shows how to remedy the problem by validating the user input against a known fixed string.

    From 31b541410fda8bb73ffe1e5790ea31c68e1ee325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:46:29 +0800 Subject: [PATCH 7/8] BigDecimalDOS.ql - Modify the format of the help document. Co-authored-by: Marcono1234 --- .../ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql index 1629871feed0..12b4cd31dbaa 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql @@ -1,7 +1,7 @@ /** * @id java/BigDecimalDOS * @name Java-BigDecimal-DOS-Vulnerability - * @description When user-controllable data is pass to the relevant Methods in BigDecimal, it may cause DOS issues when computing resources are limited. This issue is common in business scenarios such as e-commerce platforms. + * @description When user-controllable data is passed to the relevant methods in BigDecimal, it may cause DOS issues when computing resources are limited. This issue is common in business scenarios such as e-commerce platforms. * @kind path-problem * @problem.severity error */ From 3e214c8a14ae6542f5e61ad091165afd629998ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TonghuaRoot=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 24 Sep 2021 10:47:01 +0800 Subject: [PATCH 8/8] BigDecimalDOS.ql - Modify the format of the help document. Co-authored-by: Marcono1234 --- .../ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql index 12b4cd31dbaa..95a521728d22 100644 --- a/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql +++ b/java/ql/src/experimental/Security/BigDecimalDOS/BigDecimalDOS.ql @@ -27,5 +27,5 @@ class BigDecimalDOSConfig extends TaintTracking::Configuration { from BigDecimalDOSConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) -select source.getNode(), source, sink, "Potential Java BigDecimal DOS Issue due to $@.", +select source.getNode(), source, sink, "Potential Java BigDecimal DOS issue due to $@.", source.getNode(), "a user-provided value"