Skip to content

Commit bfa14fa

Browse files
authored
Merge pull request #7823 from JLLeitschuh/improve/JLL/combined_http_headers
Java: Add HTTP Request Splitting to Netty Query
2 parents 5a90214 + ded8d64 commit bfa14fa

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
public class NettyRequestSplitting {
2+
// BAD: Disables the internal response splitting verification
3+
private final DefaultHttpHeaders badHeaders = new DefaultHttpHeaders(false);
4+
5+
// GOOD: Verifies headers passed don't contain CRLF characters
6+
private final DefaultHttpHeaders goodHeaders = new DefaultHttpHeaders();
7+
8+
// BAD: Disables the internal response splitting verification
9+
private final DefaultHttpRequest badRequest = new DefaultHttpRequest(httpVersion, method, uri, false);
10+
11+
// GOOD: Verifies headers passed don't contain CRLF characters
12+
private final DefaultHttpRequest goodResponse = new DefaultHttpRequest(httpVersion, method, uri);
13+
}

java/ql/src/Security/CWE/CWE-113/NettyResponseSplitting.ql

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,82 @@
77
* @problem.severity error
88
* @security-severity 6.1
99
* @precision high
10-
* @id java/netty-http-response-splitting
10+
* @id java/netty-http-request-or-response-splitting
1111
* @tags security
12+
* external/cwe/cwe-93
1213
* external/cwe/cwe-113
1314
*/
1415

1516
import java
17+
import semmle.code.java.dataflow.FlowSources
1618

17-
abstract private class InsecureNettyObjectCreation extends ClassInstanceExpr { }
19+
abstract private class InsecureNettyObjectCreation extends ClassInstanceExpr {
20+
int vulnerableArgumentIndex;
1821

19-
private class InsecureDefaultHttpHeadersClassInstantiation extends InsecureNettyObjectCreation {
22+
InsecureNettyObjectCreation() {
23+
DataFlow::localExprFlow(any(CompileTimeConstantExpr ctce | ctce.getBooleanValue() = false),
24+
this.getArgument(vulnerableArgumentIndex))
25+
}
26+
27+
abstract string splittingType();
28+
}
29+
30+
abstract private class RequestOrResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
31+
override string splittingType() { result = "Request splitting or response splitting" }
32+
}
33+
34+
/**
35+
* Request splitting can allowing an attacker to inject/smuggle an additional HTTP request into the socket connection.
36+
*/
37+
abstract private class RequestSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
38+
override string splittingType() { result = "Request splitting" }
39+
}
40+
41+
/**
42+
* Response splitting can lead to HTTP vulnerabilities like XSS and cache poisoning.
43+
*/
44+
abstract private class ResponseSplittingInsecureNettyObjectCreation extends InsecureNettyObjectCreation {
45+
override string splittingType() { result = "Response splitting" }
46+
}
47+
48+
private class InsecureDefaultHttpHeadersClassInstantiation extends RequestOrResponseSplittingInsecureNettyObjectCreation {
2049
InsecureDefaultHttpHeadersClassInstantiation() {
21-
getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpHeaders") and
22-
getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = false
50+
this.getConstructedType()
51+
.hasQualifiedName("io.netty.handler.codec.http",
52+
["DefaultHttpHeaders", "CombinedHttpHeaders"]) and
53+
vulnerableArgumentIndex = 0
2354
}
2455
}
2556

26-
private class InsecureDefaultHttpResponseClassInstantiation extends InsecureNettyObjectCreation {
57+
private class InsecureDefaultHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation {
2758
InsecureDefaultHttpResponseClassInstantiation() {
28-
getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpResponse") and
29-
getArgument(2).(CompileTimeConstantExpr).getBooleanValue() = false
59+
this.getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpResponse") and
60+
vulnerableArgumentIndex = 2
61+
}
62+
}
63+
64+
private class InsecureDefaultHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation {
65+
InsecureDefaultHttpRequestClassInstantiation() {
66+
this.getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultHttpRequest") and
67+
vulnerableArgumentIndex = 3
3068
}
3169
}
3270

33-
private class InsecureDefaultFullHttpResponseClassInstantiation extends InsecureNettyObjectCreation {
71+
private class InsecureDefaultFullHttpResponseClassInstantiation extends ResponseSplittingInsecureNettyObjectCreation {
3472
InsecureDefaultFullHttpResponseClassInstantiation() {
35-
getConstructedType().hasQualifiedName("io.netty.handler.codec.http", "DefaultFullHttpResponse") and
36-
getArgument(3).(CompileTimeConstantExpr).getBooleanValue() = false
73+
this.getConstructedType()
74+
.hasQualifiedName("io.netty.handler.codec.http", "DefaultFullHttpResponse") and
75+
vulnerableArgumentIndex = [2, 3]
76+
}
77+
}
78+
79+
private class InsecureDefaultFullHttpRequestClassInstantiation extends RequestSplittingInsecureNettyObjectCreation {
80+
InsecureDefaultFullHttpRequestClassInstantiation() {
81+
this.getConstructedType()
82+
.hasQualifiedName("io.netty.handler.codec.http", "DefaultFullHttpRequest") and
83+
vulnerableArgumentIndex = [3, 4]
3784
}
3885
}
3986

4087
from InsecureNettyObjectCreation new
41-
select new, "Response-splitting vulnerability due to header value verification being disabled."
88+
select new, new.splittingType() + " vulnerability due to header value verification being disabled."

java/ql/src/Security/CWE/CWE-113/ResponseSplitting.qhelp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@
55

66
<overview>
77
<p>Directly writing user input (for example, an HTTP request parameter) to an HTTP header
8-
can lead to an HTTP response-splitting vulnerability.
9-
If the user input includes blank lines in it, and if the servlet container does not itself
10-
escape the blank lines, then a remote user can cause the response to turn into two separate
11-
responses, one of which is controlled by the remote user.</p>
8+
can lead to an HTTP request-splitting or response-splitting vulnerability.</p>
9+
10+
<p>HTTP response splitting can lead to vulnerabilities such as XSS and cache poisoning.</p>
11+
<p>HTTP request splitting can allow an attacker to inject an additional HTTP request into a client's outgoing socket connection.
12+
This can allow an attacker to perform an SSRF-like attack.</p>
13+
14+
<p>In the context of a servlet container, if the user input includes blank lines
15+
and the servlet container does not escape the blank lines,
16+
then a remote user can cause the response to turn into two separate responses.
17+
The remote user can then control one or more responses, which is also HTTP response splitting.</p>
1218
</overview>
1319

1420
<recommendation>
1521
<p>Guard against HTTP header splitting in the same way as guarding against cross-site scripting.
1622
Before passing any data into HTTP headers, either check the data for special characters, or
1723
escape any special characters that are present.</p>
24+
25+
<p>If the code calls Netty API's directly, ensure that the <code>validateHeaders</code> parameter is set to <code>true</code>.</p>
1826
</recommendation>
1927

2028
<example>
@@ -33,6 +41,13 @@ The second way will verify the parameters before using them to build the HTTP re
3341
<sample src="NettyResponseSplitting.java" />
3442
</example>
3543

44+
<example>
45+
<p>The following example shows the use of the netty library with configurations for verification of HTTP request splitting.
46+
The second recommended approach in the example verifies the parameters before using them to build the HTTP request.</p>
47+
48+
<sample src="NettyRequestSplitting.java" />
49+
</example>
50+
3651
<references>
3752
<li>
3853
InfosecWriters: <a href="http://www.infosecwriters.com/Papers/DCrab_HTTP_Response.pdf">HTTP response splitting</a>.
@@ -44,5 +59,8 @@ OWASP:
4459
<li>
4560
Wikipedia: <a href="http://en.wikipedia.org/wiki/HTTP_response_splitting">HTTP response splitting</a>.
4661
</li>
62+
<li>
63+
CAPEC: <a href="https://capec.mitre.org/data/definitions/105.html">CAPEC-105: HTTP Request Splitting</a>
64+
</li>
4765
</references>
4866
</qhelp>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
category: breaking
3+
---
4+
* Add more classes to Netty request/response splitting. Change identification to `java/netty-http-request-or-response-splitting`.
5+
Identify request splitting differently from response splitting in query results.
6+
Support addional classes:
7+
* `io.netty.handler.codec.http.CombinedHttpHeaders`
8+
* `io.netty.handler.codec.http.DefaultHttpRequest`
9+
* `io.netty.handler.codec.http.DefaultFullHttpRequest`

0 commit comments

Comments
 (0)