Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 272e4f6

Browse files
committed
Update the query
1 parent 2dc38ae commit 272e4f6

4 files changed

Lines changed: 121 additions & 24 deletions

File tree

java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ check on maximum allowed sleep time is enforced.</p>
2626

2727
<references>
2828
<li>
29-
snyk:
29+
Snyk:
3030
<a href="https://snyk.io/vuln/SNYK-JAVA-COMGOOGLECODEGWTUPLOAD-569506">Denial of Service (DoS)
3131
in com.googlecode.gwtupload:gwtupload</a>.
3232
</li>

java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.ql

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,14 @@ class InitParameterInput extends LocalUserInput {
4040
}
4141

4242
private class LessThanSanitizer extends DataFlow::BarrierGuard {
43-
LessThanSanitizer() { this instanceof LTExpr }
43+
LessThanSanitizer() { this instanceof ComparisonExpr }
4444

4545
override predicate checks(Expr e, boolean branch) {
46-
e = this.(LTExpr).getLeftOperand() and
46+
e = this.(ComparisonExpr).getLesserOperand() and
4747
branch = true
48+
or
49+
e = this.(ComparisonExpr).getGreaterOperand() and
50+
branch = false
4851
}
4952
}
5053

@@ -59,13 +62,11 @@ class ThreadResourceAbuse extends TaintTracking::Configuration {
5962
override predicate isSink(DataFlow::Node sink) { sink instanceof PauseThreadSink }
6063

6164
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
62-
exists(ConditionalExpr ce | ce.getAChildExpr() = node1.asExpr() and ce = node2.asExpr()) // request.getParameter("nodelay") != null ? 0 : sleepTime
63-
or
6465
exists(
6566
Method rm, ClassInstanceExpr ce, Argument arg, FieldAccess fa // thread.start() invokes the run() method of thread implementation
6667
|
6768
rm.hasName("run") and
68-
ce.getConstructedType() = rm.getSourceDeclaration().getDeclaringType() and
69+
ce.getConstructedType().getSourceDeclaration() = rm.getSourceDeclaration().getDeclaringType() and
6970
ce.getConstructedType().getASupertype*().hasQualifiedName("java.lang", "Runnable") and
7071
ce.getAnArgument() = arg and
7172
fa = rm.getAnAccessedField().getAnAccess() and
Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
edges
2-
| ThreadResourceAbuse.java:15:25:15:57 | getParameter(...) : String | ThreadResourceAbuse.java:18:28:18:36 | delayTime : Number |
3-
| ThreadResourceAbuse.java:18:28:18:36 | delayTime : Number | ThreadResourceAbuse.java:62:18:62:25 | waitTime |
4-
| ThreadResourceAbuse.java:25:25:25:73 | getInitParameter(...) : String | ThreadResourceAbuse.java:28:28:28:36 | delayTime : Number |
5-
| ThreadResourceAbuse.java:28:28:28:36 | delayTime : Number | ThreadResourceAbuse.java:62:18:62:25 | waitTime |
6-
| ThreadResourceAbuse.java:97:27:97:43 | getValue(...) : String | ThreadResourceAbuse.java:100:34:100:42 | delayTime |
2+
| ThreadResourceAbuse.java:18:25:18:57 | getParameter(...) : String | ThreadResourceAbuse.java:21:28:21:36 | delayTime : Number |
3+
| ThreadResourceAbuse.java:21:28:21:36 | delayTime : Number | ThreadResourceAbuse.java:74:18:74:25 | waitTime |
4+
| ThreadResourceAbuse.java:29:82:29:114 | getParameter(...) : String | ThreadResourceAbuse.java:30:28:30:36 | delayTime : Number |
5+
| ThreadResourceAbuse.java:30:28:30:36 | delayTime : Number | ThreadResourceAbuse.java:74:18:74:25 | waitTime |
6+
| ThreadResourceAbuse.java:37:25:37:73 | getInitParameter(...) : String | ThreadResourceAbuse.java:40:28:40:36 | delayTime : Number |
7+
| ThreadResourceAbuse.java:40:28:40:36 | delayTime : Number | ThreadResourceAbuse.java:74:18:74:25 | waitTime |
8+
| ThreadResourceAbuse.java:141:27:141:43 | getValue(...) : String | ThreadResourceAbuse.java:144:34:144:42 | delayTime |
9+
| ThreadResourceAbuse.java:172:19:172:50 | getHeader(...) : String | ThreadResourceAbuse.java:177:17:177:26 | retryAfter |
710
nodes
8-
| ThreadResourceAbuse.java:15:25:15:57 | getParameter(...) : String | semmle.label | getParameter(...) : String |
9-
| ThreadResourceAbuse.java:18:28:18:36 | delayTime : Number | semmle.label | delayTime : Number |
10-
| ThreadResourceAbuse.java:25:25:25:73 | getInitParameter(...) : String | semmle.label | getInitParameter(...) : String |
11-
| ThreadResourceAbuse.java:28:28:28:36 | delayTime : Number | semmle.label | delayTime : Number |
12-
| ThreadResourceAbuse.java:62:18:62:25 | waitTime | semmle.label | waitTime |
13-
| ThreadResourceAbuse.java:97:27:97:43 | getValue(...) : String | semmle.label | getValue(...) : String |
14-
| ThreadResourceAbuse.java:100:34:100:42 | delayTime | semmle.label | delayTime |
11+
| ThreadResourceAbuse.java:18:25:18:57 | getParameter(...) : String | semmle.label | getParameter(...) : String |
12+
| ThreadResourceAbuse.java:21:28:21:36 | delayTime : Number | semmle.label | delayTime : Number |
13+
| ThreadResourceAbuse.java:29:82:29:114 | getParameter(...) : String | semmle.label | getParameter(...) : String |
14+
| ThreadResourceAbuse.java:30:28:30:36 | delayTime : Number | semmle.label | delayTime : Number |
15+
| ThreadResourceAbuse.java:37:25:37:73 | getInitParameter(...) : String | semmle.label | getInitParameter(...) : String |
16+
| ThreadResourceAbuse.java:40:28:40:36 | delayTime : Number | semmle.label | delayTime : Number |
17+
| ThreadResourceAbuse.java:74:18:74:25 | waitTime | semmle.label | waitTime |
18+
| ThreadResourceAbuse.java:141:27:141:43 | getValue(...) : String | semmle.label | getValue(...) : String |
19+
| ThreadResourceAbuse.java:144:34:144:42 | delayTime | semmle.label | delayTime |
20+
| ThreadResourceAbuse.java:172:19:172:50 | getHeader(...) : String | semmle.label | getHeader(...) : String |
21+
| ThreadResourceAbuse.java:177:17:177:26 | retryAfter | semmle.label | retryAfter |
1522
#select
16-
| ThreadResourceAbuse.java:62:18:62:25 | waitTime | ThreadResourceAbuse.java:15:25:15:57 | getParameter(...) : String | ThreadResourceAbuse.java:62:18:62:25 | waitTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:15:25:15:57 | getParameter(...) | user-provided value |
17-
| ThreadResourceAbuse.java:62:18:62:25 | waitTime | ThreadResourceAbuse.java:25:25:25:73 | getInitParameter(...) : String | ThreadResourceAbuse.java:62:18:62:25 | waitTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:25:25:25:73 | getInitParameter(...) | user-provided value |
18-
| ThreadResourceAbuse.java:100:34:100:42 | delayTime | ThreadResourceAbuse.java:97:27:97:43 | getValue(...) : String | ThreadResourceAbuse.java:100:34:100:42 | delayTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:97:27:97:43 | getValue(...) | user-provided value |
23+
| ThreadResourceAbuse.java:74:18:74:25 | waitTime | ThreadResourceAbuse.java:18:25:18:57 | getParameter(...) : String | ThreadResourceAbuse.java:74:18:74:25 | waitTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:18:25:18:57 | getParameter(...) | user-provided value |
24+
| ThreadResourceAbuse.java:74:18:74:25 | waitTime | ThreadResourceAbuse.java:29:82:29:114 | getParameter(...) : String | ThreadResourceAbuse.java:74:18:74:25 | waitTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:29:82:29:114 | getParameter(...) | user-provided value |
25+
| ThreadResourceAbuse.java:74:18:74:25 | waitTime | ThreadResourceAbuse.java:37:25:37:73 | getInitParameter(...) : String | ThreadResourceAbuse.java:74:18:74:25 | waitTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:37:25:37:73 | getInitParameter(...) | user-provided value |
26+
| ThreadResourceAbuse.java:144:34:144:42 | delayTime | ThreadResourceAbuse.java:141:27:141:43 | getValue(...) : String | ThreadResourceAbuse.java:144:34:144:42 | delayTime | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:141:27:141:43 | getValue(...) | user-provided value |
27+
| ThreadResourceAbuse.java:177:17:177:26 | retryAfter | ThreadResourceAbuse.java:172:19:172:50 | getHeader(...) : String | ThreadResourceAbuse.java:177:17:177:26 | retryAfter | Vulnerability of uncontrolled resource consumption due to $@. | ThreadResourceAbuse.java:172:19:172:50 | getHeader(...) | user-provided value |

java/ql/test/experimental/query-tests/security/CWE-400/ThreadResourceAbuse.java

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import javax.servlet.http.HttpServletResponse;
1111

1212
public class ThreadResourceAbuse extends HttpServlet {
13+
static final int DEFAULT_RETRY_AFTER = 5*1000;
14+
static final int MAX_RETRY_AFTER = 10*1000;
15+
1316
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
1417
// Get thread pause time from request parameter
1518
String delayTimeStr = request.getParameter("DelayTime");
@@ -20,6 +23,15 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
2023
}
2124
}
2225

26+
protected void doGet2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
27+
// Get thread pause time from request parameter
28+
try {
29+
int delayTime = request.getParameter("nodelay") != null ? 0 : Integer.valueOf(request.getParameter("DelayTime"));
30+
new UncheckedSyncAction(delayTime).start();
31+
} catch (NumberFormatException e) {
32+
}
33+
}
34+
2335
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2436
// Get thread pause time from init container parameter
2537
String delayTimeStr = getServletContext().getInitParameter("DelayTime");
@@ -78,11 +90,43 @@ public CheckedSyncAction(int waitTime) {
7890
public void run() {
7991
try {
8092
if (waitTime > 0 && waitTime < 5000) {
81-
Thread.sleep(waitTime);
93+
Thread.sleep(waitTime);
94+
// Do other updates
95+
}
96+
} catch (InterruptedException e) {
97+
}
98+
}
99+
}
100+
101+
class CheckedSyncAction2 extends Thread {
102+
int waitTime;
103+
104+
public CheckedSyncAction2(int waitTime) {
105+
this.waitTime = waitTime;
106+
}
107+
108+
// GOOD: enforce an upper limit on wait time
109+
@Override
110+
public void run() {
111+
try {
112+
if (waitTime >= 5000) {
113+
// No action
114+
} else {
115+
Thread.sleep(waitTime);
116+
}
82117
// Do other updates
118+
} catch (InterruptedException e) {
83119
}
84-
} catch (InterruptedException e) {
85-
}
120+
}
121+
}
122+
123+
protected void doPost2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
124+
// Get thread pause time from init container parameter
125+
String delayTimeStr = getServletContext().getInitParameter("DelayTime");
126+
try {
127+
int delayTime = Integer.valueOf(delayTimeStr);
128+
new CheckedSyncAction2(delayTime).start();
129+
} catch (NumberFormatException e) {
86130
}
87131
}
88132

@@ -105,4 +149,47 @@ protected void doHead(HttpServletRequest request, HttpServletResponse response)
105149
}
106150
}
107151
}
152+
153+
int parseReplyAfter(String value) {
154+
if (value == null || value.isEmpty()) {
155+
return DEFAULT_RETRY_AFTER;
156+
}
157+
158+
try {
159+
int n = Integer.parseInt(value);
160+
if (n < 0) {
161+
return DEFAULT_RETRY_AFTER;
162+
}
163+
164+
return Math.min(n, MAX_RETRY_AFTER);
165+
} catch (NumberFormatException e) {
166+
return DEFAULT_RETRY_AFTER;
167+
}
168+
}
169+
170+
protected void doHead2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
171+
// Get thread pause time from request header
172+
String header = request.getHeader("Retry-After");
173+
int retryAfter = Integer.parseInt(header);
174+
175+
try {
176+
// BAD: wait for retry-after without input validation
177+
Thread.sleep(retryAfter);
178+
} catch (InterruptedException ignore) {
179+
// ignore
180+
}
181+
}
182+
183+
protected void doHead3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
184+
// Get thread pause time from request header
185+
String header = request.getHeader("Retry-After");
186+
int retryAfter = parseReplyAfter(header);
187+
188+
try {
189+
// GOOD: wait for retry-after with input validation
190+
Thread.sleep(retryAfter);
191+
} catch (InterruptedException ignore) {
192+
// ignore
193+
}
194+
}
108195
}

0 commit comments

Comments
 (0)