Merge pull request #3702 from esbena/js/memory-exhaustion

JS: add query js/memory-exhaustion
This commit is contained in:
Asger F
2020-06-19 20:35:57 +01:00
committed by GitHub
21 changed files with 871 additions and 0 deletions

View File

@@ -41,6 +41,7 @@
| Creating biased random numbers from a cryptographically secure source (`js/biased-cryptographic-random`) | security, external/cwe/cwe-327 | Highlights mathematical operations on cryptographically secure numbers that can create biased results. Results are shown on LGTM by default. | | Creating biased random numbers from a cryptographically secure source (`js/biased-cryptographic-random`) | security, external/cwe/cwe-327 | Highlights mathematical operations on cryptographically secure numbers that can create biased results. Results are shown on LGTM by default. |
| Storage of sensitive information in build artifact (`js/build-artifact-leak`) | security, external/cwe/cwe-312 | Highlights storage of sensitive information in build artifacts. Results are shown on LGTM by default. | | Storage of sensitive information in build artifact (`js/build-artifact-leak`) | security, external/cwe/cwe-312 | Highlights storage of sensitive information in build artifacts. Results are shown on LGTM by default. |
| 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. | | 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. |
| Resource exhaustion (`js/resource-exhaustion`) | security, external/cwe/cwe-770 | Highlights operations that may cause the resources of the application to be exhausted. Results are shown on LGTM by default. |
## Changes to existing queries ## Changes to existing queries

View File

@@ -44,6 +44,7 @@
+ semmlecode-javascript-queries/Security/CWE-730/RegExpInjection.ql: /Security/CWE/CWE-730 + semmlecode-javascript-queries/Security/CWE-730/RegExpInjection.ql: /Security/CWE/CWE-730
+ semmlecode-javascript-queries/Security/CWE-754/UnvalidatedDynamicMethodCall.ql: /Security/CWE/CWE-754 + semmlecode-javascript-queries/Security/CWE-754/UnvalidatedDynamicMethodCall.ql: /Security/CWE/CWE-754
+ semmlecode-javascript-queries/Security/CWE-770/MissingRateLimiting.ql: /Security/CWE/CWE-770 + semmlecode-javascript-queries/Security/CWE-770/MissingRateLimiting.ql: /Security/CWE/CWE-770
+ semmlecode-javascript-queries/Security/CWE-770/ResourceExhaustion.ql: /Security/CWE/CWE-770
+ semmlecode-javascript-queries/Security/CWE-776/XmlBomb.ql: /Security/CWE/CWE-776 + semmlecode-javascript-queries/Security/CWE-776/XmlBomb.ql: /Security/CWE/CWE-776
+ semmlecode-javascript-queries/Security/CWE-798/HardcodedCredentials.ql: /Security/CWE/CWE-798 + semmlecode-javascript-queries/Security/CWE-798/HardcodedCredentials.ql: /Security/CWE/CWE-798
+ semmlecode-javascript-queries/Security/CWE-807/ConditionalBypass.ql: /Security/CWE/CWE-807 + semmlecode-javascript-queries/Security/CWE-807/ConditionalBypass.ql: /Security/CWE/CWE-807

View File

@@ -0,0 +1,113 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Applications are constrained by how many resources they can make use
of. Failing to respect these constraints may cause the application to
be unresponsive or crash. It is therefore problematic if attackers
can control the sizes or lifetimes of allocated objects.
</p>
</overview>
<recommendation>
<p>
Ensure that attackers can not control object sizes and their
lifetimes. If object sizes and lifetimes must be controlled by
external parties, ensure you restrict the object sizes and lifetimes so that
they are within acceptable ranges.
</p>
</recommendation>
<example>
<p>
The following example allocates a buffer with a user-controlled
size.
</p>
<sample src="examples/ResourceExhaustion_buffer.js" />
<p>
This is problematic since an attacker can choose a size
that makes the application run out of memory. Even worse, in older
versions of Node.js, this could leak confidential memory.
To prevent such attacks, limit the buffer size:
</p>
<sample src="examples/ResourceExhaustion_buffer_fixed.js" />
</example>
<example>
<p>
As another example, consider an application that allocates an
array with a user-controlled size, and then fills it with values:
</p>
<sample src="examples/ResourceExhaustion_array.js" />
<p>
The allocation of the array itself is not problematic since arrays are
allocated sparsely, but the subsequent filling of the array will take
a long time, causing the application to be unresponsive, or even run
out of memory.
Again, a limit on the size will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_array_fixed.js" />
</example>
<example>
<p>
Finally, the following example lets a user choose a delay after
which a function is executed:
</p>
<sample src="examples/ResourceExhaustion_timeout.js" />
<p>
This is problematic because a large delay essentially makes the
application wait indefinitely before executing the function. Repeated
registrations of such delays will therefore use up all of the memory
in the application.
Again, a limit on the delay will prevent the attack:
</p>
<sample src="examples/ResourceExhaustion_timeout_fixed.js" />
</example>
<references>
</references>
</qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name Resource exhaustion
* @description Allocating objects or timers with user-controlled
* sizes or durations can cause resource exhaustion.
* @kind path-problem
* @problem.severity warning
* @id js/resource-exhaustion
* @precision high
* @tags security
* external/cwe/cwe-770
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.ResourceExhaustion::ResourceExhaustion
from Configuration dataflow, DataFlow::PathNode source, DataFlow::PathNode sink
where dataflow.hasFlowPath(source, sink)
select sink, source, sink, sink.getNode().(Sink).getProblemDescription() + " from $@.", source,
"here"

View File

@@ -0,0 +1,10 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
let dogs = new Array(size).fill(x => "dog"); // BAD
// ... use the dogs
});

View File

@@ -0,0 +1,16 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
if (size > 1024) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
let dogs = new Array(size).fill(x => "dog"); // GOOD
// ... use the dogs
});

View File

@@ -0,0 +1,10 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
let buffer = Buffer.alloc(size); // BAD
// ... use the buffer
});

View File

@@ -0,0 +1,16 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
if (size > 1024) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
let buffer = Buffer.alloc(size); // GOOD
// ... use the buffer
});

View File

@@ -0,0 +1,9 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var delay = parseInt(url.parse(req.url, true).query.delay);
setTimeout(f, delay); // BAD
});

View File

@@ -0,0 +1,15 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var delay = parseInt(url.parse(req.url, true).query.delay);
if (delay > 1000) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
setTimeout(f, delay); // GOOD
});

View File

@@ -0,0 +1,77 @@
/**
* Provides a taint tracking configuration for reasoning about
* resource exhaustion vulnerabilities (CWE-770).
*
* Note, for performance reasons: only import this file if
* `ResourceExhaustion::Configuration` is needed, otherwise
* `ResourceExhaustionCustomizations` should be imported instead.
*/
import javascript
import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations
module ResourceExhaustion {
import ResourceExhaustionCustomizations::ResourceExhaustion
/**
* A data flow configuration for resource exhaustion vulnerabilities.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "ResourceExhaustion" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source.(Source).getAFlowLabel() = label
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink.(Sink).getAFlowLabel() = label
}
override predicate isAdditionalFlowStep(
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
DataFlow::FlowLabel dstlabel
) {
dstlabel instanceof Label::Number and
isNumericFlowStep(src, dst)
or
// reuse most existing taint steps
super.isAdditionalFlowStep(src, dst) and
not dst.asExpr() instanceof AddExpr and
if dst.(DataFlow::MethodCallNode).calls(src, "toString")
then dstlabel.isTaint()
else srclabel = dstlabel
}
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
guard instanceof LoopBoundInjection::LengthCheckSanitizerGuard or
guard instanceof UpperBoundsCheckSanitizerGuard or
guard instanceof TypeTestGuard
}
}
/**
* Holds if data may flow from `src` to `dst` as a number.
*/
predicate isNumericFlowStep(DataFlow::Node src, DataFlow::Node dst) {
// steps that introduce or preserve a number
dst.(DataFlow::PropRead).accesses(src, ["length", "size"])
or
exists(DataFlow::CallNode c |
c = dst and
src = c.getAnArgument()
|
c = DataFlow::globalVarRef("Math").getAMemberCall(_) or
c = DataFlow::globalVarRef(["Number", "parseInt", "parseFloat"]).getACall()
)
or
exists(Expr dstExpr, Expr srcExpr |
dstExpr = dst.asExpr() and
srcExpr = src.asExpr()
|
dstExpr.(BinaryExpr).getAnOperand() = srcExpr and
not dstExpr instanceof AddExpr
or
dstExpr.(PlusExpr).getOperand() = srcExpr
)
}
}

View File

@@ -0,0 +1,187 @@
/**
* Provides default sources, sinks and sanitizers for reasoning about
* resource exhaustion vulnerabilities, as well as extension points for
* adding your own.
*/
import javascript
module ResourceExhaustion {
/**
* A data flow source for resource exhaustion vulnerabilities.
*/
abstract class Source extends DataFlow::Node {
/** Gets a flow label denoting the type of value for which this is a source. */
DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
}
/**
* A data flow sink for resource exhaustion vulnerabilities.
*/
abstract class Sink extends DataFlow::Node {
/** Gets a flow label denoting the type of value for which this is a sink. */
DataFlow::FlowLabel getAFlowLabel() { result instanceof Label::Number }
/**
* Gets a description of why this is a problematic sink.
*/
abstract string getProblemDescription();
}
/**
* A data flow sanitizer for resource exhaustion vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* Provides data flow labels for resource exhaustion vulnerabilities.
*/
module Label {
/**
* A number data flow label.
*/
class Number extends DataFlow::FlowLabel {
Number() { this = "number" }
}
}
/**
* A sanitizer that blocks taint flow if the size of a number is limited.
*/
class UpperBoundsCheckSanitizerGuard extends TaintTracking::LabeledSanitizerGuardNode,
DataFlow::ValueNode {
override RelationalComparison astNode;
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
label instanceof Label::Number and
(
true = outcome and
e = astNode.getLesserOperand()
or
false = outcome and
e = astNode.getGreaterOperand()
)
}
}
/**
* A test of form `typeof x === "something"`, preventing `x` from being a number in some cases.
*/
class TypeTestGuard extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::ValueNode {
override EqualityTest astNode;
TypeofExpr typeof;
boolean polarity;
TypeTestGuard() {
astNode.getAnOperand() = typeof and
(
// typeof x === "number" sanitizes `x` when it evaluates to false
astNode.getAnOperand().getStringValue() = "number" and
polarity = astNode.getPolarity().booleanNot()
or
// typeof x === "string" sanitizes `x` when it evaluates to true
astNode.getAnOperand().getStringValue() != "number" and
polarity = astNode.getPolarity()
)
}
override predicate sanitizes(boolean outcome, Expr e, DataFlow::FlowLabel label) {
polarity = outcome and
e = typeof.getOperand() and
label instanceof Label::Number
}
}
/** A source of remote user input, considered as a data flow source for resource exhaustion vulnerabilities. */
class RemoteFlowSourceAsSource extends Source {
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
}
/**
* A node that determines the size of a buffer, considered as a data flow sink for resource exhaustion vulnerabilities.
*/
class BufferSizeSink extends Sink {
BufferSizeSink() {
exists(DataFlow::SourceNode clazz, DataFlow::InvokeNode invk, int index |
clazz = DataFlow::globalVarRef("Buffer") and this = invk.getArgument(index)
|
exists(string name |
invk = clazz.getAMemberCall(name) and
(
name = "from" and index = 2
or
name = ["alloc", "allocUnsafe", "allocUnsafeSlow"] and index = 0
)
)
or
invk = clazz.getAnInvocation() and
(
invk.getNumArgument() = 1 and
index = 0
or
invk.getNumArgument() = 3 and index = 2
)
)
or
this = DataFlow::globalVarRef("SlowBuffer").getAnInstantiation().getArgument(0)
}
override string getProblemDescription() {
result = "This creates a buffer with a user-controlled size"
}
}
/**
* A node that determines the size of an array, considered as a data flow sink for resource exhaustion vulnerabilities.
*/
class DenseArraySizeSink extends Sink {
DenseArraySizeSink() {
// Arrays are sparse by default, so we must also look at how the array is used
exists(DataFlow::ArrayConstructorInvokeNode instance |
this = instance.getArgument(0) and
instance.getNumArgument() = 1
|
exists(instance.getAMethodCall(["map", "fill", "join", "toString"])) or
instance.flowsToExpr(any(AddExpr p).getAnOperand())
)
}
override string getProblemDescription() {
result = "This creates an array with a user-controlled length"
}
}
/**
* A node that determines the repetitions of a string, considered as a data flow sink for resource exhaustion vulnerabilities.
*/
class StringRepetitionSink extends Sink {
StringRepetitionSink() {
exists(DataFlow::MethodCallNode repeat |
repeat.getMethodName() = "repeat" and
this = repeat.getArgument(0)
)
}
override DataFlow::FlowLabel getAFlowLabel() { any() }
override string getProblemDescription() {
result = "This creates a string with a user-controlled length"
}
}
/**
* A node that determines the duration of a timer, considered as a data flow sink for resource exhaustion vulnerabilities.
*/
class TimerDurationSink extends Sink {
TimerDurationSink() {
this = DataFlow::globalVarRef(["setTimeout", "setInterval"]).getACall().getArgument(1) or
this = LodashUnderscore::member(["delay", "throttle", "debounce"]).getACall().getArgument(1)
}
override DataFlow::FlowLabel getAFlowLabel() { any() }
override string getProblemDescription() {
result = "This creates a timer with a user-controlled duration"
}
}
}

View File

@@ -0,0 +1,234 @@
nodes
| documentation_examples/ResourceExhaustion_array.js:5:6:5:57 | size |
| documentation_examples/ResourceExhaustion_array.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:51 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url |
| documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url |
| documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size |
| documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size |
| documentation_examples/ResourceExhaustion_buffer.js:5:6:5:57 | size |
| documentation_examples/ResourceExhaustion_buffer.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:51 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url |
| documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url |
| documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size |
| documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size |
| documentation_examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url |
| documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url |
| documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay |
| documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay |
| resource-exhaustion.js:5:7:5:42 | s |
| resource-exhaustion.js:5:11:5:34 | url.par ... , true) |
| resource-exhaustion.js:5:11:5:40 | url.par ... ).query |
| resource-exhaustion.js:5:11:5:42 | url.par ... query.s |
| resource-exhaustion.js:5:21:5:27 | req.url |
| resource-exhaustion.js:5:21:5:27 | req.url |
| resource-exhaustion.js:6:7:6:21 | n |
| resource-exhaustion.js:6:11:6:21 | parseInt(s) |
| resource-exhaustion.js:6:20:6:20 | s |
| resource-exhaustion.js:12:21:12:21 | n |
| resource-exhaustion.js:12:21:12:21 | n |
| resource-exhaustion.js:13:21:13:21 | n |
| resource-exhaustion.js:13:21:13:21 | n |
| resource-exhaustion.js:14:16:14:16 | n |
| resource-exhaustion.js:14:16:14:16 | n |
| resource-exhaustion.js:15:22:15:22 | n |
| resource-exhaustion.js:15:22:15:22 | n |
| resource-exhaustion.js:16:26:16:26 | n |
| resource-exhaustion.js:16:26:16:26 | n |
| resource-exhaustion.js:18:14:18:14 | n |
| resource-exhaustion.js:18:14:18:14 | n |
| resource-exhaustion.js:20:20:20:20 | n |
| resource-exhaustion.js:20:20:20:20 | n |
| resource-exhaustion.js:22:18:22:18 | n |
| resource-exhaustion.js:22:18:22:18 | n |
| resource-exhaustion.js:27:9:27:9 | n |
| resource-exhaustion.js:27:9:27:9 | n |
| resource-exhaustion.js:28:13:28:13 | n |
| resource-exhaustion.js:28:13:28:13 | n |
| resource-exhaustion.js:29:9:29:9 | n |
| resource-exhaustion.js:29:9:29:9 | n |
| resource-exhaustion.js:30:9:30:9 | n |
| resource-exhaustion.js:30:9:30:9 | n |
| resource-exhaustion.js:31:9:31:9 | n |
| resource-exhaustion.js:31:9:31:9 | n |
| resource-exhaustion.js:32:9:32:9 | n |
| resource-exhaustion.js:32:9:32:9 | n |
| resource-exhaustion.js:34:12:34:12 | n |
| resource-exhaustion.js:34:12:34:12 | n |
| resource-exhaustion.js:35:12:35:12 | s |
| resource-exhaustion.js:35:12:35:12 | s |
| resource-exhaustion.js:37:14:37:14 | n |
| resource-exhaustion.js:37:14:37:18 | n * x |
| resource-exhaustion.js:37:14:37:18 | n * x |
| resource-exhaustion.js:45:14:45:25 | Math.ceil(s) |
| resource-exhaustion.js:45:14:45:25 | Math.ceil(s) |
| resource-exhaustion.js:45:24:45:24 | s |
| resource-exhaustion.js:46:14:46:22 | Number(s) |
| resource-exhaustion.js:46:14:46:22 | Number(s) |
| resource-exhaustion.js:46:21:46:21 | s |
| resource-exhaustion.js:50:14:50:14 | s |
| resource-exhaustion.js:50:14:50:21 | s.length |
| resource-exhaustion.js:50:14:50:21 | s.length |
| resource-exhaustion.js:55:16:55:16 | n |
| resource-exhaustion.js:55:16:55:16 | n |
| resource-exhaustion.js:58:7:58:20 | ns |
| resource-exhaustion.js:58:12:58:20 | x ? n : s |
| resource-exhaustion.js:58:16:58:16 | n |
| resource-exhaustion.js:59:14:59:15 | ns |
| resource-exhaustion.js:59:14:59:15 | ns |
| resource-exhaustion.js:66:16:66:16 | n |
| resource-exhaustion.js:66:16:66:16 | n |
| resource-exhaustion.js:70:16:70:16 | n |
| resource-exhaustion.js:70:16:70:16 | n |
| resource-exhaustion.js:81:17:81:17 | n |
| resource-exhaustion.js:81:17:81:17 | n |
| resource-exhaustion.js:82:17:82:17 | s |
| resource-exhaustion.js:82:17:82:17 | s |
| resource-exhaustion.js:83:18:83:18 | n |
| resource-exhaustion.js:83:18:83:18 | n |
| resource-exhaustion.js:84:18:84:18 | s |
| resource-exhaustion.js:84:18:84:18 | s |
edges
| documentation_examples/ResourceExhaustion_array.js:5:6:5:57 | size | documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size |
| documentation_examples/ResourceExhaustion_array.js:5:6:5:57 | size | documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size |
| documentation_examples/ResourceExhaustion_array.js:5:13:5:57 | parseIn ... y.size) | documentation_examples/ResourceExhaustion_array.js:5:6:5:57 | size |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:45 | url.par ... , true) | documentation_examples/ResourceExhaustion_array.js:5:22:5:51 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:51 | url.par ... ).query | documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:51 | url.par ... ).query | documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size | documentation_examples/ResourceExhaustion_array.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_array.js:5:22:5:56 | url.par ... ry.size | documentation_examples/ResourceExhaustion_array.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_array.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_array.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_buffer.js:5:6:5:57 | size | documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size |
| documentation_examples/ResourceExhaustion_buffer.js:5:6:5:57 | size | documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size |
| documentation_examples/ResourceExhaustion_buffer.js:5:13:5:57 | parseIn ... y.size) | documentation_examples/ResourceExhaustion_buffer.js:5:6:5:57 | size |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:45 | url.par ... , true) | documentation_examples/ResourceExhaustion_buffer.js:5:22:5:51 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:51 | url.par ... ).query | documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:51 | url.par ... ).query | documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size | documentation_examples/ResourceExhaustion_buffer.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_buffer.js:5:22:5:56 | url.par ... ry.size | documentation_examples/ResourceExhaustion_buffer.js:5:13:5:57 | parseIn ... y.size) |
| documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_buffer.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_buffer.js:5:22:5:45 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay | documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) | documentation_examples/ResourceExhaustion_timeout.js:5:6:5:59 | delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) | documentation_examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:52 | url.par ... ).query | documentation_examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay |
| documentation_examples/ResourceExhaustion_timeout.js:5:23:5:58 | url.par ... y.delay | documentation_examples/ResourceExhaustion_timeout.js:5:14:5:59 | parseIn ... .delay) |
| documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentation_examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) |
| documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentation_examples/ResourceExhaustion_timeout.js:5:23:5:46 | url.par ... , true) |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:6:20:6:20 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:35:12:35:12 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:45:24:45:24 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:46:21:46:21 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:50:14:50:14 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:82:17:82:17 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s |
| resource-exhaustion.js:5:7:5:42 | s | resource-exhaustion.js:84:18:84:18 | s |
| resource-exhaustion.js:5:11:5:34 | url.par ... , true) | resource-exhaustion.js:5:11:5:40 | url.par ... ).query |
| resource-exhaustion.js:5:11:5:40 | url.par ... ).query | resource-exhaustion.js:5:11:5:42 | url.par ... query.s |
| resource-exhaustion.js:5:11:5:42 | url.par ... query.s | resource-exhaustion.js:5:7:5:42 | s |
| resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) |
| resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:5:11:5:34 | url.par ... , true) |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:12:21:12:21 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:12:21:12:21 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:13:21:13:21 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:13:21:13:21 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:14:16:14:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:15:22:15:22 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:16:26:16:26 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:18:14:18:14 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:18:14:18:14 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:20:20:20:20 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:22:18:22:18 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:27:9:27:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:28:13:28:13 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:29:9:29:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:30:9:30:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:31:9:31:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:32:9:32:9 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:34:12:34:12 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:37:14:37:14 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:55:16:55:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:55:16:55:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:58:16:58:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:66:16:66:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:66:16:66:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:70:16:70:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:70:16:70:16 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:81:17:81:17 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n |
| resource-exhaustion.js:6:7:6:21 | n | resource-exhaustion.js:83:18:83:18 | n |
| resource-exhaustion.js:6:11:6:21 | parseInt(s) | resource-exhaustion.js:6:7:6:21 | n |
| resource-exhaustion.js:6:20:6:20 | s | resource-exhaustion.js:6:11:6:21 | parseInt(s) |
| resource-exhaustion.js:37:14:37:14 | n | resource-exhaustion.js:37:14:37:18 | n * x |
| resource-exhaustion.js:37:14:37:14 | n | resource-exhaustion.js:37:14:37:18 | n * x |
| resource-exhaustion.js:45:24:45:24 | s | resource-exhaustion.js:45:14:45:25 | Math.ceil(s) |
| resource-exhaustion.js:45:24:45:24 | s | resource-exhaustion.js:45:14:45:25 | Math.ceil(s) |
| resource-exhaustion.js:46:21:46:21 | s | resource-exhaustion.js:46:14:46:22 | Number(s) |
| resource-exhaustion.js:46:21:46:21 | s | resource-exhaustion.js:46:14:46:22 | Number(s) |
| resource-exhaustion.js:50:14:50:14 | s | resource-exhaustion.js:50:14:50:21 | s.length |
| resource-exhaustion.js:50:14:50:14 | s | resource-exhaustion.js:50:14:50:21 | s.length |
| resource-exhaustion.js:58:7:58:20 | ns | resource-exhaustion.js:59:14:59:15 | ns |
| resource-exhaustion.js:58:7:58:20 | ns | resource-exhaustion.js:59:14:59:15 | ns |
| resource-exhaustion.js:58:12:58:20 | x ? n : s | resource-exhaustion.js:58:7:58:20 | ns |
| resource-exhaustion.js:58:16:58:16 | n | resource-exhaustion.js:58:12:58:20 | x ? n : s |
#select
| documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size | documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_array.js:7:23:7:26 | size | This creates an array with a user-controlled length from $@. | documentation_examples/ResourceExhaustion_array.js:5:32:5:38 | req.url | here |
| documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size | documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url | documentation_examples/ResourceExhaustion_buffer.js:7:28:7:31 | size | This creates a buffer with a user-controlled size from $@. | documentation_examples/ResourceExhaustion_buffer.js:5:32:5:38 | req.url | here |
| documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | documentation_examples/ResourceExhaustion_timeout.js:7:16:7:20 | delay | This creates a timer with a user-controlled duration from $@. | documentation_examples/ResourceExhaustion_timeout.js:5:33:5:39 | req.url | here |
| resource-exhaustion.js:12:21:12:21 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:12:21:12:21 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:13:21:13:21 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:13:21:13:21 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:14:16:14:16 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:14:16:14:16 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:15:22:15:22 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:15:22:15:22 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:16:26:16:26 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:16:26:16:26 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:18:14:18:14 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:18:14:18:14 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:20:20:20:20 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:20:20:20:20 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:22:18:22:18 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:22:18:22:18 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:27:9:27:9 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:27:9:27:9 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:28:13:28:13 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:28:13:28:13 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:29:9:29:9 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:29:9:29:9 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:30:9:30:9 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:30:9:30:9 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:31:9:31:9 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:31:9:31:9 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:32:9:32:9 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:32:9:32:9 | n | This creates an array with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:34:12:34:12 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:34:12:34:12 | n | This creates a string with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:35:12:35:12 | s | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:35:12:35:12 | s | This creates a string with a user-controlled length from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:37:14:37:18 | n * x | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:37:14:37:18 | n * x | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:45:14:45:25 | Math.ceil(s) | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:45:14:45:25 | Math.ceil(s) | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:46:14:46:22 | Number(s) | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:46:14:46:22 | Number(s) | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:50:14:50:21 | s.length | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:50:14:50:21 | s.length | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:55:16:55:16 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:55:16:55:16 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:59:14:59:15 | ns | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:59:14:59:15 | ns | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:66:16:66:16 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:66:16:66:16 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:70:16:70:16 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:70:16:70:16 | n | This creates a buffer with a user-controlled size from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:81:17:81:17 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:81:17:81:17 | n | This creates a timer with a user-controlled duration from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:82:17:82:17 | s | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:82:17:82:17 | s | This creates a timer with a user-controlled duration from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:83:18:83:18 | n | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:83:18:83:18 | n | This creates a timer with a user-controlled duration from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |
| resource-exhaustion.js:84:18:84:18 | s | resource-exhaustion.js:5:21:5:27 | req.url | resource-exhaustion.js:84:18:84:18 | s | This creates a timer with a user-controlled duration from $@. | resource-exhaustion.js:5:21:5:27 | req.url | here |

View File

@@ -0,0 +1 @@
Security/CWE-770/ResourceExhaustion.ql

View File

@@ -0,0 +1,10 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
let dogs = new Array(size).fill(x => "dog"); // BAD
// ... use the dog
});

View File

@@ -0,0 +1,16 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
if (size > 1024) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
let dogs = new Array(size).fill(x => "dog"); // GOOD
// ... use the dogs
});

View File

@@ -0,0 +1,10 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
let buffer = Buffer.alloc(size); // BAD
// ... use the buffer
});

View File

@@ -0,0 +1,16 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var size = parseInt(url.parse(req.url, true).query.size);
if (size > 1024) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
let buffer = Buffer.alloc(size); // GOOD
// ... use the buffer
});

View File

@@ -0,0 +1,9 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var delay = parseInt(url.parse(req.url, true).query.delay);
setTimeout(f, delay); // BAD
});

View File

@@ -0,0 +1,15 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
var delay = parseInt(url.parse(req.url, true).query.delay);
if (delay > 1000) {
res.statusCode = 400;
res.end("Bad request.");
return;
}
setTimeout(f, delay); // GOOD
});

View File

@@ -0,0 +1,85 @@
var http = require("http"),
url = require("url");
var server = http.createServer(function(req, res) {
let s = url.parse(req.url, true).query.s;
let n = parseInt(s);
Buffer.from(s); // OK
Buffer.from(n); // OK
Buffer.from(x, n); // OK
Buffer.from(x, y, s); // NOT OK
Buffer.from(x, y, n); // NOT OK
Buffer.from(x, y, n); // NOT OK
Buffer.alloc(n); // NOT OK
Buffer.allocUnsafe(n); // NOT OK
Buffer.allocUnsafeSlow(n); // NOT OK
new Buffer(n); // NOT OK
new Buffer(x, n); // OK
new Buffer(x, y, n); // NOT OK
new SlowBuffer(n); // NOT OK
Array(n); // OK
new Array(n); // OK
Array(n).map(); // NOT OK
new Array(n).map(); // NOT OK
Array(n).fill(); // NOT OK
Array(n).join(); // NOT OK
Array(n).toString(); // NOT OK
Array(n) + x; // NOT OK
x.repeat(n); // NOT OK
x.repeat(s); // NOT OK
new Buffer(n * x); // NOT OK
new Buffer(n + n); // NOT OK [INCONSISTENCY]
new Buffer(n + x); // OK (maybe)
new Buffer(n + s); // OK (this is a string if `s` is a string)
new Buffer(s + 2); // OK (this is a string if `s` is a string)
new Buffer(s + s); // OK
new Buffer(n + "X"); // OK
new Buffer(Math.ceil(s)); // NOT OK
new Buffer(Number(s)); // NOT OK
new Buffer(new Number(s)); // OK
new Buffer(s + x.length); // OK (this is a string if `s` is a string)
new Buffer(s.length); // NOT OK
if (n < 100) {
new Buffer(n); // OK
} else {
new Buffer(n); // NOT OK
}
let ns = x ? n : s;
new Buffer(ns); // NOT OK
new Buffer(n.toString()); // OK
if (typeof n === "string") {
new Buffer(n); // OK
} else {
new Buffer(n); // NOT OK
}
if (typeof n === "number") {
new Buffer(n); // NOT OK
} else {
new Buffer(n); // OK
}
if (typeof s === "number") {
new Buffer(s); // NOT OK [INCONSISTENCY]
} else {
new Buffer(s); // OK
}
setTimeout(f, n); // NOT OK
setTimeout(f, s); // NOT OK
setInterval(f, n); // NOT OK
setInterval(f, s); // NOT OK
});