Skip to content

Commit d4cc58f

Browse files
committed
JS: documentation for js/unclosed-stream
1 parent 2988d73 commit d4cc58f

File tree

5 files changed

+92
-10
lines changed

5 files changed

+92
-10
lines changed

Diff for: change-notes/1.25/analysis-javascript.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
| Unsafe expansion of self-closing HTML tag (`js/unsafe-html-expansion`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities caused by unsafe expansion of self-closing HTML tags. |
3838
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | correctness, security, external/cwe/cwe-078, external/cwe/cwe-088 | Highlights potential command injections due to a shell command being constructed from library inputs. Results are shown on LGTM by default. |
3939
| Improper code sanitization (`js/bad-code-sanitization`) | security, external/cwe/cwe-094, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights string concatenation where code is constructed without proper sanitization. Results are shown on LGTM by default. |
40+
| Unclosed stream (`js/unclosed-stream`) | security, external/cwe/cwe-404, external/cwe/cwe-730 | Highlights stream processors that do not close their stream when they should. Results are shown on LGTM by default. |
4041

4142
## Changes to existing queries
4243

Diff for: javascript/config/suites/javascript/security

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
+ semmlecode-javascript-queries/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql: /Security/CWE/CWE-640
4343
+ semmlecode-javascript-queries/Security/CWE-643/XpathInjection.ql: /Security/CWE/CWE-643
4444
+ semmlecode-javascript-queries/Security/CWE-730/RegExpInjection.ql: /Security/CWE/CWE-730
45+
+ semmlecode-javascript-queries/Security/CWE-730/UnclosedStream.ql: /Security/CWE/CWE-730
4546
+ semmlecode-javascript-queries/Security/CWE-754/UnvalidatedDynamicMethodCall.ql: /Security/CWE/CWE-754
4647
+ semmlecode-javascript-queries/Security/CWE-770/MissingRateLimiting.ql: /Security/CWE/CWE-770
4748
+ semmlecode-javascript-queries/Security/CWE-776/XmlBomb.ql: /Security/CWE/CWE-776
+57-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,69 @@
11
<!DOCTYPE qhelp PUBLIC
2-
"-//Semmle//qhelp//EN"
3-
"qhelp.dtd">
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
44
<qhelp>
55

6-
<overview>
6+
<overview>
77

8-
</overview>
8+
<p>
99

10-
<recommendation>
10+
Callback-based input streams generate calls until they are empty or
11+
closed explicitly, and they will take up system resources until
12+
that point in time.
1113

12-
</recommendation>
14+
</p>
1315

14-
<example>
16+
<p>
1517

16-
</example>
18+
Forgetting to close a stream that no longer is useful can cause
19+
unnecessary exhaustion of system resources, which may cause the
20+
application to be unresponsive or even crash.
1721

18-
<references>
22+
</p>
1923

20-
</references>
24+
</overview>
25+
26+
<recommendation>
27+
28+
<p>
29+
30+
Close input streams explicitly when there is no interest in their
31+
remaining content.
32+
33+
</p>
34+
35+
</recommendation>
36+
37+
<example>
38+
39+
<p>
40+
41+
In the following example, an array stores the content of a stream
42+
until the array becomes too big. When that happens, an error message
43+
is generated, and the stream processing is supposed to end.
44+
45+
</p>
46+
47+
<sample src="examples/UnclosedStream.js"/>
48+
49+
<p>
50+
51+
The stream will however keep invoking the callback until it becomes
52+
empty, regardless of the programmers intention to not process
53+
additional content. This means that the array will grow indefinitely, if a malicious actor keep sending data.
54+
55+
Close the stream to remedy this:
56+
57+
</p>
58+
59+
<sample src="examples/UnclosedStream_fixed.js"/>
60+
61+
</example>
62+
63+
<references>
64+
65+
<li>Node.js: <a href="https://nodejs.org/api/stream.html">Stream</a></li>
66+
67+
</references>
2168

2269
</qhelp>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
var https = require("https");
2+
3+
new Promise(function dispatchHttpRequest(resolve, reject) {
4+
https.request(options, function(stream) {
5+
var responseBuffer = [];
6+
stream.on("data", function(chunk) {
7+
responseBuffer.push(chunk);
8+
9+
if (responseBuffer.length > 1024) {
10+
reject("Input size of 1024 exceeded."); // BAD
11+
}
12+
});
13+
14+
stream.on("end", () => resolve(responseBuffer));
15+
});
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var https = require("https");
2+
3+
new Promise(function dispatchHttpRequest(resolve, reject) {
4+
https.request(options, function(stream) {
5+
var responseBuffer = [];
6+
stream.on("data", function(chunk) {
7+
responseBuffer.push(chunk);
8+
9+
if (responseBuffer.length > 1024) {
10+
stream.destroy();
11+
reject("Input size of 1024 exceeded."); // GOOD
12+
}
13+
});
14+
15+
stream.on("end", () => resolve(responseBuffer));
16+
});
17+
});

0 commit comments

Comments
 (0)