Skip to content

Commit 377aa68

Browse files
authored
Merge pull request github#12854 from natejohnson05/js-insecure-http-parser
JS - NodeJS CWE-444 InsecureHTTPParser
2 parents b6a7661 + 88411ce commit 377aa68

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
8+
<p>
9+
10+
Strict HTTP parsing may cause problems with interoperability with some
11+
non-conformant HTTP implementations. But disabling it is strongly discouraged,
12+
as it opens the door to several threats including HTTP Request Smuggling.
13+
14+
</p>
15+
16+
</overview>
17+
18+
<recommendation>
19+
20+
<p>
21+
22+
Do not enable insecure http parser.
23+
24+
</p>
25+
26+
</recommendation>
27+
28+
<example>
29+
30+
<p>
31+
32+
The following example shows the instantiation of an http server. This
33+
server is vulnerable to HTTP Request Smuggling because the
34+
<code>insecureHTTPParser</code> option of the server instantiation is
35+
set to <code>true</code>. As a consequence, malformed packets may attempt
36+
to exploit any number of weaknesses including ranging from Web Cache Poisoning
37+
Attacks to bypassing firewall protection mecahanisms.
38+
39+
</p>
40+
41+
<sample src="examples/InsecureHttpParser.js"/>
42+
43+
<p>
44+
45+
To make sure that packets are parsed correctly, the
46+
<code>invalidHTTPParser</code> option should have its default value,
47+
or be explicitly set to <code>false</code>.
48+
49+
</p>
50+
51+
</example>
52+
53+
<references>
54+
55+
<li>NodeJS: <a href="https://nodejs.org/en/blog/vulnerability/february-2020-security-releases">February 20 Security Release</a></li>
56+
57+
<li>Snyk: <a href="https://snyk.io/blog/node-js-release-fixes-a-critical-http-security-vulnerability/">NodeJS Critical HTTP Vulnerability</a></li>
58+
59+
<li>CWE-444: <a href="https://cwe.mitre.org/data/definitions/444.html">HTTP Request/Response Smuggling</a></li>
60+
61+
</references>
62+
63+
</qhelp>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @name Insecure http parser
3+
* @description Using an insecure http parser can lead to http smuggling attacks.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @security-severity 9.0
7+
* @precision high
8+
* @id js/insecure-http-parser
9+
* @tags security
10+
* external/cwe/cwe-444
11+
*/
12+
13+
import javascript
14+
15+
/** Gets options argument for a potential http or https connection */
16+
DataFlow::InvokeNode nodeInvocation() {
17+
result instanceof ClientRequest
18+
or
19+
result instanceof Http::ServerDefinition
20+
}
21+
22+
/** Gets an options object for an http or https connection. */
23+
DataFlow::ObjectLiteralNode nodeOptions() { result.flowsTo(nodeInvocation().getAnArgument()) }
24+
25+
from DataFlow::PropWrite disable
26+
where
27+
exists(DataFlow::SourceNode env |
28+
env = NodeJSLib::process().getAPropertyRead("env") and
29+
disable = env.getAPropertyWrite("NODE_OPTIONS") and
30+
disable.getRhs().getStringValue().matches("%--insecure-http-parser%")
31+
)
32+
or
33+
(
34+
disable = nodeOptions().getAPropertyWrite("insecureHTTPParser")
35+
or
36+
// the same thing, but with API-nodes if they happen to be available
37+
exists(API::Node nodeInvk | nodeInvk.getAnInvocation() = nodeInvocation() |
38+
disable.getRhs() = nodeInvk.getAParameter().getMember("insecureHTTPParser").asSink()
39+
)
40+
) and
41+
disable.getRhs().(AnalyzedNode).getTheBooleanValue() = true
42+
select disable, "Allowing invalid HTTP headers is strongly discouraged."
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const http = require('node:http');
2+
3+
http.createServer({
4+
insecureHTTPParser: true
5+
}, (req, res) => {
6+
res.end('hello world\n');
7+
});

0 commit comments

Comments
 (0)