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

Skip to content

Commit e2b7f7d

Browse files
committed
reintroduce the number sinks
1 parent 029459c commit e2b7f7d

6 files changed

Lines changed: 93 additions & 39 deletions

File tree

javascript/ql/src/experimental/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll renamed to javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionCustomizations.qll

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,59 @@ module ResourceExhaustion {
7777
result = "This creates a timer with a user-controlled duration"
7878
}
7979
}
80+
81+
/**
82+
* A node that determines the size of a buffer, considered as a data flow sink for resource exhaustion vulnerabilities.
83+
*/
84+
class BufferSizeSink extends Sink {
85+
BufferSizeSink() {
86+
exists(DataFlow::SourceNode clazz, DataFlow::InvokeNode invk, int index |
87+
clazz = DataFlow::globalVarRef("Buffer") and this = invk.getArgument(index)
88+
|
89+
exists(string name |
90+
invk = clazz.getAMemberCall(name) and
91+
(
92+
name = "from" and index = 2 // the length argument
93+
or
94+
name = ["alloc", "allocUnsafe", "allocUnsafeSlow"] and index = 0 // the buffer size
95+
)
96+
)
97+
or
98+
invk = clazz.getAnInvocation() and
99+
(
100+
invk.getNumArgument() = 1 and // `new Buffer(size)`, it's only an issue if the size is a number, which we don't track precisely.
101+
index = 0
102+
or
103+
invk.getNumArgument() = 3 and index = 2 // the length argument
104+
)
105+
)
106+
or
107+
this = DataFlow::globalVarRef("SlowBuffer").getAnInstantiation().getArgument(0)
108+
}
109+
110+
override string getProblemDescription() {
111+
result = "This creates a buffer with a user-controlled size"
112+
}
113+
}
114+
115+
/**
116+
* A node that determines the size of an array, considered as a data flow sink for resource exhaustion vulnerabilities.
117+
* This is only an issue if the argument is a number, which we don't track precisely.
118+
*/
119+
class DenseArraySizeSink extends Sink {
120+
DenseArraySizeSink() {
121+
// Arrays are sparse by default, so we must also look at how the array is used
122+
exists(DataFlow::ArrayConstructorInvokeNode instance |
123+
this = instance.getArgument(0) and
124+
instance.getNumArgument() = 1
125+
|
126+
exists(instance.getAMethodCall(["map", "fill", "join", "toString"])) or
127+
instance.flowsToExpr(any(AddExpr p).getAnOperand())
128+
)
129+
}
130+
131+
override string getProblemDescription() {
132+
result = "This creates an array with a user-controlled length"
133+
}
134+
}
80135
}

javascript/ql/src/experimental/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll renamed to javascript/ql/lib/semmle/javascript/security/dataflow/ResourceExhaustionQuery.qll

File renamed without changes.

javascript/ql/src/Security/CWE-770/ResourceExhaustion.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import javascript
1414
import DataFlow::PathGraph
15-
import experimental.semmle.javascript.security.dataflow.ResourceExhaustionQuery
15+
import semmle.javascript.security.dataflow.ResourceExhaustionQuery
1616

1717
from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink
1818
where dataflow.hasFlowPath(source, sink)

javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/Consistency.expected

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import javascript
2+
import semmle.javascript.security.dataflow.ResourceExhaustionQuery
3+
import testUtilities.ConsistencyChecking

javascript/ql/test/query-tests/Security/CWE-770/ResourceExhaustion/resource-exhaustion.js

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
// this file contains many `NOT OK [INCONSISTENCY]` annotations, those
2-
// would be resolved if the query used flow labels to recognice
3-
// numbers flowing to sinks
4-
51
var http = require("http"),
62
url = require("url");
73

@@ -13,73 +9,73 @@ var server = http.createServer(function(req, res) {
139
Buffer.from(n); // OK
1410
Buffer.from(x, n); // OK
1511
Buffer.from(x, y, s); // NOT OK
16-
Buffer.from(x, y, n); // NOT OK [INCONSISTENCY]
17-
Buffer.from(x, y, n); // NOT OK [INCONSISTENCY]
18-
Buffer.alloc(n); // NOT OK [INCONSISTENCY]
19-
Buffer.allocUnsafe(n); // NOT OK [INCONSISTENCY]
20-
Buffer.allocUnsafeSlow(n); // NOT OK [INCONSISTENCY]
12+
Buffer.from(x, y, n); // NOT OK
13+
Buffer.from(x, y, n); // NOT OK
14+
Buffer.alloc(n); // NOT OK
15+
Buffer.allocUnsafe(n); // NOT OK
16+
Buffer.allocUnsafeSlow(n); // NOT OK
2117

22-
new Buffer(n); // NOT OK [INCONSISTENCY]
18+
new Buffer(n); // NOT OK
2319
new Buffer(x, n); // OK
24-
new Buffer(x, y, n); // NOT OK [INCONSISTENCY]
20+
new Buffer(x, y, n); // NOT OK
2521

26-
new SlowBuffer(n); // NOT OK [INCONSISTENCY]
22+
new SlowBuffer(n); // NOT OK
2723

2824
Array(n); // OK
2925
new Array(n); // OK
3026

31-
Array(n).map(); // NOT OK [INCONSISTENCY]
32-
new Array(n).map(); // NOT OK [INCONSISTENCY]
33-
Array(n).fill(); // NOT OK [INCONSISTENCY]
34-
Array(n).join(); // NOT OK [INCONSISTENCY]
35-
Array(n).toString(); // NOT OK [INCONSISTENCY]
36-
Array(n) + x; // NOT OK [INCONSISTENCY]
27+
Array(n).map(); // NOT OK
28+
new Array(n).map(); // NOT OK
29+
Array(n).fill(); // NOT OK
30+
Array(n).join(); // NOT OK
31+
Array(n).toString(); // NOT OK
32+
Array(n) + x; // NOT OK
3733

3834
x.repeat(n); // NOT OK
3935
x.repeat(s); // NOT OK
4036

41-
new Buffer(n * x); // NOT OK [INCONSISTENCY]
42-
new Buffer(n + n); // NOT OK [INCONSISTENCY]
43-
new Buffer(n + x); // OK (maybe)
44-
new Buffer(n + s); // OK (this is a string if `s` is a string)
45-
new Buffer(s + 2); // OK (this is a string if `s` is a string)
46-
new Buffer(s + s); // OK
47-
new Buffer(n + "X"); // OK
37+
new Buffer(n * x); // NOT OK
38+
new Buffer(n + n); // NOT OK
39+
new Buffer(n + x); // OK (maybe) - but still flagged [INCONSISTENCY]
40+
new Buffer(n + s); // OK (this is a string if `s` is a string) - but still flagged [INCONSISTENCY]
41+
new Buffer(s + 2); // OK (this is a string if `s` is a string) - but still flagged [INCONSISTENCY]
42+
new Buffer(s + s); // OK - but still flagged [INCONSISTENCY]
43+
new Buffer(n + "X"); // OK - but still flagged [INCONSISTENCY]
4844

49-
new Buffer(Math.ceil(s)); // NOT OK [INCONSISTENCY]
50-
new Buffer(Number(s)); // NOT OK [INCONSISTENCY]
45+
new Buffer(Math.ceil(s)); // NOT OK
46+
new Buffer(Number(s)); // NOT OK
5147
new Buffer(new Number(s)); // OK
5248

53-
new Buffer(s + x.length); // OK (this is a string if `s` is a string)
54-
new Buffer(s.length); // NOT OK [INCONSISTENCY]
49+
new Buffer(s + x.length); // OK (this is a string if `s` is a string) - but still flagged [INCONSISTENCY]
50+
new Buffer(s.length); // NOT OK
5551

5652
if (n < 100) {
5753
new Buffer(n); // OK
5854
} else {
59-
new Buffer(n); // NOT OK [INCONSISTENCY]
55+
new Buffer(n); // NOT OK
6056
}
6157

6258
let ns = x ? n : s;
63-
new Buffer(ns); // NOT OK [INCONSISTENCY]
59+
new Buffer(ns); // NOT OK
6460

65-
new Buffer(n.toString()); // OK
61+
new Buffer(n.toString()); // OK - but still flagged [INCONSISTENCY]
6662

6763
if (typeof n === "string") {
68-
new Buffer(n); // OK
64+
new Buffer(n); // OK - but still flagged [INCONSISTENCY]
6965
} else {
70-
new Buffer(n); // NOT OK [INCONSISTENCY]
66+
new Buffer(n); // NOT OK
7167
}
7268

7369
if (typeof n === "number") {
74-
new Buffer(n); // NOT OK [INCONSISTENCY]
70+
new Buffer(n); // NOT OK
7571
} else {
76-
new Buffer(n); // OK
72+
new Buffer(n); // OK - but still flagged [INCONSISTENCY]
7773
}
7874

7975
if (typeof s === "number") {
80-
new Buffer(s); // NOT OK [INCONSISTENCY]
76+
new Buffer(s); // NOT OK
8177
} else {
82-
new Buffer(s); // OK
78+
new Buffer(s); // OK - but stil flagged [INCONSISTENCY]
8379
}
8480

8581
setTimeout(f, n); // NOT OK

0 commit comments

Comments
 (0)