Skip to content

Commit a0f4a51

Browse files
committed
Insecure HTTP parser query for JavaScript
1 parent 5ee9711 commit a0f4a51

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 6.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+
// from DataFlow::CallNode call
16+
// where
17+
// call = DataFlow::moduleMember(importLib(), memberCall()).getACall() and
18+
// call.getOptionArgument(0, "insecureHTTPParser").analyze().getABooleanValue() = true or
19+
// call.getOptionArgument(1, "insecureHTTPParser").analyze().getABooleanValue() = true
20+
// select call.getOptionArgument(0, "insecureHTTPParser"),
21+
// "This argument allows the use of an insecure parser that accepts invalid HTTP headers."
22+
23+
/** Gets options argument for a potential http or https connection */
24+
DataFlow::InvokeNode nodeInvocation() {
25+
result instanceof ClientRequest
26+
or
27+
result instanceof Http::ServerDefinition
28+
}
29+
30+
/** Gets an options object for an http or https connection. */
31+
DataFlow::ObjectLiteralNode nodeOptions() { result.flowsTo(nodeInvocation().getAnArgument()) }
32+
33+
from DataFlow::PropWrite disable
34+
where
35+
disable = nodeOptions().getAPropertyWrite("insecureHTTPParser")
36+
or
37+
// the same thing, but with API-nodes if they happen to be available
38+
exists(API::Node nodeInvk | nodeInvk.getAnInvocation() = nodeInvocation() |
39+
disable.getRhs() = nodeInvk.getAParameter().getMember("insecureHTTPParser").asSink()
40+
)
41+
and
42+
disable.getRhs().(AnalyzedNode).getTheBooleanValue() = true
43+
select disable, "Allowing invalid HTTP headers is strongly discouraged."
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// test NodeJS
2+
const https = require('node:https');
3+
const http = require('node:http');
4+
5+
https.createServer({
6+
insecureHTTPParser: true
7+
}, (req, res) => {
8+
res.writeHead(200);
9+
res.end('hello world\n');
10+
});
11+
12+
http.createServer({
13+
insecureHTTPParser: true
14+
}, (req, res) => {
15+
res.writeHead(200);
16+
res.end('hello world\n');
17+
});
18+
19+
http.get({ insecureHTTPParser: true }, (res) => {
20+
res.writeHead(200);
21+
res.end('hello world\n');
22+
});
23+
24+
http.get('url', { insecureHTTPParser: true }, (res) => {
25+
res.writeHead(200);
26+
res.end('hello world\n');
27+
});
28+
29+
http.request({ insecureHTTPParser: true }, (res) => {
30+
res.writeHead(200);
31+
res.end('hello world\n');
32+
});
33+
34+
http.request('url', { insecureHTTPParser: true }, (res) => {
35+
res.writeHead(200);
36+
res.end('hello world\n');
37+
});

0 commit comments

Comments
 (0)