зеркало из https://github.com/github/codeql.git
Merge branch 'master' of github.com:Semmle/ql into js/more-fs-modules
This commit is contained in:
Коммит
4625217a68
|
@ -44,7 +44,7 @@
|
|||
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
|
||||
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
|
||||
| Polynomial regular expression used on uncontrolled data (`js/polynomial-redos`) | security, external/cwe/cwe-730, external/cwe/cwe-400 | Highlights expensive regular expressions that may be used on malicious input. Results are shown on LGTM by default. |
|
||||
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive copying operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
|
||||
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive assignment operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
|
||||
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
|
||||
| Unnecessary use of `cat` process (`js/unnecessary-use-of-cat`) | correctness, security, maintainability | Highlights command executions of `cat` where the fs API should be used instead. Results are shown on LGTM by default. |
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ private predicate isChiForAllAliasedMemory(Instruction instr) {
|
|||
or
|
||||
isChiForAllAliasedMemory(instr.(ChiInstruction).getTotal())
|
||||
or
|
||||
isChiForAllAliasedMemory(instr.(PhiInstruction).getAnInput())
|
||||
isChiForAllAliasedMemory(instr.(PhiInstruction).getAnInputOperand().getAnyDef())
|
||||
}
|
||||
|
||||
private predicate modelTaintToReturnValue(Function f, int parameterIn) {
|
||||
|
|
|
@ -135,6 +135,12 @@ private module VirtualDispatch {
|
|||
exists(FunctionInstruction fi |
|
||||
this.flowsFrom(DataFlow::instructionNode(fi), _) and
|
||||
result = fi.getFunctionSymbol()
|
||||
) and
|
||||
(
|
||||
this.getNumberOfArguments() <= result.getEffectiveNumberOfParameters() and
|
||||
this.getNumberOfArguments() >= result.getEffectiveNumberOfParameters()
|
||||
or
|
||||
result.isVarargs()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1202,6 +1202,11 @@ class CallInstruction extends Instruction {
|
|||
final Instruction getPositionalArgument(int index) {
|
||||
result = getPositionalArgumentOperand(index).getDef()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1202,6 +1202,11 @@ class CallInstruction extends Instruction {
|
|||
final Instruction getPositionalArgument(int index) {
|
||||
result = getPositionalArgumentOperand(index).getDef()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1202,6 +1202,11 @@ class CallInstruction extends Instruction {
|
|||
final Instruction getPositionalArgument(int index) {
|
||||
result = getPositionalArgumentOperand(index).getDef()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1202,6 +1202,11 @@ class CallInstruction extends Instruction {
|
|||
final Instruction getPositionalArgument(int index) {
|
||||
result = getPositionalArgumentOperand(index).getDef()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1202,6 +1202,11 @@ class CallInstruction extends Instruction {
|
|||
final Instruction getPositionalArgument(int index) {
|
||||
result = getPositionalArgumentOperand(index).getDef()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,6 +100,13 @@ predicate signaturesMatch(MethodSignature method, MethodSignature other) {
|
|||
method.getName() = other.getName() and
|
||||
// same number of parameters.
|
||||
method.getBody().getNumParameter() = other.getBody().getNumParameter() and
|
||||
// same this parameter (if exists)
|
||||
(
|
||||
not exists(method.getBody().getThisTypeAnnotation()) and
|
||||
not exists(other.getBody().getThisTypeAnnotation())
|
||||
or
|
||||
method.getBody().getThisTypeAnnotation().getType() = other.getBody().getThisTypeAnnotation().getType()
|
||||
) and
|
||||
// The types are compared in matchingCallSignature. This is sanity-check that the textual representation of the type-annotations are somewhat similar.
|
||||
forall(int i | i in [0 .. -1 + method.getBody().getNumParameter()] |
|
||||
getParameterTypeAnnotation(method, i) = getParameterTypeAnnotation(other, i)
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
<p>
|
||||
One way to cause prototype pollution is through use of an unsafe <em>merge</em> or <em>extend</em> function
|
||||
to recursively copy properties from one object to another.
|
||||
to recursively copy properties from one object to another, or through the use of a <em>deep assignment</em>
|
||||
function to assign to an unverified chain of property names.
|
||||
Such a function has the potential to modify any object reachable from the destination object, and
|
||||
the built-in <code>Object.prototype</code> is usually reachable through the special properties
|
||||
<code>__proto__</code> and <code>constructor.prototype</code>.
|
||||
|
@ -23,13 +24,13 @@
|
|||
<recommendation>
|
||||
<p>
|
||||
The most effective place to guard against this is in the function that performs
|
||||
the recursive copy.
|
||||
the recursive copy or deep assignment.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Only merge a property recursively when it is an own property of the <em>destination</em> object.
|
||||
Only merge or assign a property recursively when it is an own property of the <em>destination</em> object.
|
||||
Alternatively, blacklist the property names <code>__proto__</code> and <code>constructor</code>
|
||||
from being merged.
|
||||
from being merged or assigned to.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @name Prototype pollution in utility function
|
||||
* @description Recursively copying properties between objects may cause
|
||||
* accidental modification of a built-in prototype object.
|
||||
* @description Recursively assigning properties on objects may cause
|
||||
* accidental modification of a built-in prototype object.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
|
@ -16,6 +16,81 @@ import DataFlow
|
|||
import PathGraph
|
||||
import semmle.javascript.DynamicPropertyAccess
|
||||
|
||||
/**
|
||||
* A call of form `x.split(".")` where `x` is a parameter.
|
||||
*
|
||||
* We restrict this to parameter nodes to focus on "deep assignment" functions.
|
||||
*/
|
||||
class SplitCall extends MethodCallNode {
|
||||
SplitCall() {
|
||||
getMethodName() = "split" and
|
||||
getArgument(0).mayHaveStringValue(".") and
|
||||
getReceiver().getALocalSource() instanceof ParameterNode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred -> succ` should preserve polluted property names.
|
||||
*/
|
||||
predicate copyArrayStep(SourceNode pred, SourceNode succ) {
|
||||
// x -> [...x]
|
||||
exists(SpreadElement spread |
|
||||
pred.flowsTo(spread.getOperand().flow()) and
|
||||
succ.asExpr().(ArrayExpr).getAnElement() = spread
|
||||
)
|
||||
or
|
||||
// `x -> y` in `y.push( x[i] )`
|
||||
exists(MethodCallNode push |
|
||||
push = succ.getAMethodCall("push") and
|
||||
(
|
||||
getAnEnumeratedArrayElement(pred).flowsTo(push.getAnArgument())
|
||||
or
|
||||
pred.flowsTo(push.getASpreadArgument())
|
||||
)
|
||||
)
|
||||
or
|
||||
// x -> x.concat(...)
|
||||
exists(MethodCallNode concat_ |
|
||||
concat_.getMethodName() = "concat" and
|
||||
(pred = concat_.getReceiver() or pred = concat_.getAnArgument()) and
|
||||
succ = concat_
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` may refer to a `SplitCall` or a copy thereof, possibly
|
||||
* returned through a function call.
|
||||
*/
|
||||
predicate isSplitArray(SourceNode node) {
|
||||
node instanceof SplitCall
|
||||
or
|
||||
exists(SourceNode pred | isSplitArray(pred) |
|
||||
copyArrayStep(pred, node)
|
||||
or
|
||||
pred.flowsToExpr(node.(CallNode).getACallee().getAReturnedExpr())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A property name originating from a `x.split(".")` call.
|
||||
*/
|
||||
class SplitPropName extends SourceNode {
|
||||
SourceNode array;
|
||||
|
||||
SplitPropName() {
|
||||
isSplitArray(array) and
|
||||
this = getAnEnumeratedArrayElement(array)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array from which this property name was obtained (the result from `split`).
|
||||
*/
|
||||
SourceNode getArray() { result = array }
|
||||
|
||||
/** Gets an element accessed on the same underlying array. */
|
||||
SplitPropName getAnAlias() { result.getArray() = getArray() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the properties of `node` are enumerated locally.
|
||||
*/
|
||||
|
@ -24,13 +99,23 @@ predicate arePropertiesEnumerated(DataFlow::SourceNode node) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` may flow from an enumerated prop name, possibly
|
||||
* into function calls (but not returns).
|
||||
* Holds if `node` is a source of property names that we consider possible
|
||||
* prototype pollution payloads.
|
||||
*/
|
||||
predicate isEnumeratedPropName(Node node) {
|
||||
predicate isPollutedPropNameSource(DataFlow::Node node) {
|
||||
node instanceof EnumeratedPropName
|
||||
or
|
||||
exists(Node pred | isEnumeratedPropName(pred) |
|
||||
node instanceof SplitPropName
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` may flow from a source of polluted propery names, possibly
|
||||
* into function calls (but not returns).
|
||||
*/
|
||||
predicate isPollutedPropName(Node node) {
|
||||
isPollutedPropNameSource(node)
|
||||
or
|
||||
exists(Node pred | isPollutedPropName(pred) |
|
||||
node = pred.getASuccessor()
|
||||
or
|
||||
argumentPassingStep(_, pred, _, node)
|
||||
|
@ -51,7 +136,7 @@ predicate isEnumeratedPropName(Node node) {
|
|||
predicate isPotentiallyObjectPrototype(SourceNode node) {
|
||||
exists(Node base, Node key |
|
||||
dynamicPropReadStep(base, key, node) and
|
||||
isEnumeratedPropName(key) and
|
||||
isPollutedPropName(key) and
|
||||
// Ignore cases where the properties of `base` are enumerated, to avoid FPs
|
||||
// where the key came from that enumeration (and thus will not return Object.prototype).
|
||||
// For example, `src[key]` in `for (let key in src) { ... src[key] ... }` will generally
|
||||
|
@ -85,7 +170,13 @@ predicate dynamicPropWrite(DataFlow::Node base, DataFlow::Node prop, DataFlow::N
|
|||
// Prune writes that are unlikely to modify Object.prototype.
|
||||
// This is mainly for performance, but may block certain results due to
|
||||
// not tracking out of function returns and into callbacks.
|
||||
isPotentiallyObjectPrototype(base.getALocalSource())
|
||||
isPotentiallyObjectPrototype(base.getALocalSource()) and
|
||||
// Ignore writes with an obviously safe RHS.
|
||||
not exists(Expr e | e = rhs.asExpr() |
|
||||
e instanceof Literal or
|
||||
e instanceof ObjectExpr or
|
||||
e instanceof ArrayExpr
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -141,10 +232,10 @@ class PropNameTracking extends DataFlow::Configuration {
|
|||
|
||||
override predicate isSource(DataFlow::Node node, FlowLabel label) {
|
||||
label instanceof UnsafePropLabel and
|
||||
exists(EnumeratedPropName prop |
|
||||
node = prop
|
||||
(
|
||||
isPollutedPropNameSource(node)
|
||||
or
|
||||
node = prop.getASourceProp()
|
||||
node = any(EnumeratedPropName prop).getASourceProp()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -404,22 +495,29 @@ string deriveExprName(DataFlow::Node node) {
|
|||
result = getExprName(node)
|
||||
or
|
||||
not exists(getExprName(node)) and
|
||||
result = "this object"
|
||||
result = "here"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the dynamic property write `base[prop] = rhs` can pollute the prototype
|
||||
* of `base` due to flow from `enum`.
|
||||
* of `base` due to flow from `propNameSource`.
|
||||
*
|
||||
* In most cases this will result in an alert, the exception being the case where
|
||||
* `base` does not have a prototype at all.
|
||||
*/
|
||||
predicate isPrototypePollutingAssignment(Node base, Node prop, Node rhs, EnumeratedPropName enum) {
|
||||
predicate isPrototypePollutingAssignment(Node base, Node prop, Node rhs, Node propNameSource) {
|
||||
dynamicPropWrite(base, prop, rhs) and
|
||||
isPollutedPropNameSource(propNameSource) and
|
||||
exists(PropNameTracking cfg |
|
||||
cfg.hasFlow(enum, base) and
|
||||
cfg.hasFlow(enum, prop) and
|
||||
cfg.hasFlow(enum.getASourceProp(), rhs)
|
||||
cfg.hasFlow(propNameSource, base) and
|
||||
if propNameSource instanceof EnumeratedPropName
|
||||
then
|
||||
cfg.hasFlow(propNameSource, prop) and
|
||||
cfg.hasFlow(propNameSource.(EnumeratedPropName).getASourceProp(), rhs)
|
||||
else (
|
||||
cfg.hasFlow(propNameSource.(SplitPropName).getAnAlias(), prop) and
|
||||
rhs.getALocalSource() instanceof ParameterNode
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -464,18 +562,29 @@ class ObjectCreateNullCall extends CallNode {
|
|||
}
|
||||
|
||||
from
|
||||
PropNameTracking cfg, DataFlow::PathNode source, DataFlow::PathNode sink, EnumeratedPropName enum,
|
||||
Node base
|
||||
PropNameTracking cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Node prop, Node base,
|
||||
string msg, Node col1, Node col2
|
||||
where
|
||||
isPollutedPropName(prop) and
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
isPrototypePollutingAssignment(base, _, _, enum) and
|
||||
isPrototypePollutingAssignment(base, _, _, prop) and
|
||||
sink.getNode() = base and
|
||||
source.getNode() = enum and
|
||||
source.getNode() = prop and
|
||||
(
|
||||
getANodeLeadingToBaseBase(base) instanceof ObjectLiteralNode
|
||||
or
|
||||
not getANodeLeadingToBaseBase(base) instanceof ObjectCreateNullCall
|
||||
) and
|
||||
// Generate different messages for deep merge and deep assign cases.
|
||||
if prop instanceof EnumeratedPropName
|
||||
then (
|
||||
col1 = prop.(EnumeratedPropName).getSourceObject() and
|
||||
col2 = base and
|
||||
msg = "Properties are copied from $@ to $@ without guarding against prototype pollution."
|
||||
) else (
|
||||
col1 = prop and
|
||||
col2 = base and
|
||||
msg =
|
||||
"The property chain $@ is recursively assigned to $@ without guarding against prototype pollution."
|
||||
)
|
||||
select base, source, sink,
|
||||
"Properties are copied from $@ to $@ without guarding against prototype pollution.",
|
||||
enum.getSourceObject(), deriveExprName(enum.getSourceObject()), base, deriveExprName(base)
|
||||
select base, source, sink, msg, col1, deriveExprName(col1), col2, deriveExprName(col2)
|
||||
|
|
|
@ -11,7 +11,7 @@ private import semmle.javascript.dataflow.internal.FlowSteps
|
|||
* Gets a node that refers to an element of `array`, likely obtained
|
||||
* as a result of enumerating the elements of the array.
|
||||
*/
|
||||
private SourceNode getAnEnumeratedArrayElement(SourceNode array) {
|
||||
SourceNode getAnEnumeratedArrayElement(SourceNode array) {
|
||||
exists(MethodCallNode call, string name |
|
||||
call = array.getAMethodCall(name) and
|
||||
(name = "forEach" or name = "map") and
|
||||
|
|
|
@ -58,6 +58,40 @@ module InclusionTest {
|
|||
boolean getPolarity() { result = true }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a utility function (`callee`) that performs an InclusionTest (`inner`).
|
||||
*/
|
||||
private class IndirectInclusionTest extends Range, DataFlow::CallNode {
|
||||
InclusionTest inner;
|
||||
Function callee;
|
||||
|
||||
IndirectInclusionTest() {
|
||||
inner.getEnclosingExpr() = callee.getAReturnedExpr() and
|
||||
this.getACallee() = callee and
|
||||
count(this.getACallee()) = 1 and
|
||||
count(callee.getAReturnedExpr()) = 1 and
|
||||
not this.isImprecise() and
|
||||
inner.getContainerNode().getALocalSource().getEnclosingExpr() = callee.getAParameter() and
|
||||
inner.getContainedNode().getALocalSource().getEnclosingExpr() = callee.getAParameter()
|
||||
}
|
||||
|
||||
override DataFlow::Node getContainerNode() {
|
||||
exists(int arg |
|
||||
inner.getContainerNode().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getContainedNode() {
|
||||
exists(int arg |
|
||||
inner.getContainedNode().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override boolean getPolarity() { result = inner.getPolarity() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a method named `includes`, assumed to refer to `String.prototype.includes`
|
||||
* or `Array.prototype.includes`.
|
||||
|
|
|
@ -56,6 +56,40 @@ module StringOps {
|
|||
boolean getPolarity() { result = true }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a utility function (`callee`) that performs a StartsWith check (`inner`).
|
||||
*/
|
||||
private class IndirectStartsWith extends Range, DataFlow::CallNode {
|
||||
StartsWith inner;
|
||||
Function callee;
|
||||
|
||||
IndirectStartsWith() {
|
||||
inner.getEnclosingExpr() = callee.getAReturnedExpr() and
|
||||
this.getACallee() = callee and
|
||||
count(this.getACallee()) = 1 and
|
||||
count(callee.getAReturnedExpr()) = 1 and
|
||||
not this.isImprecise() and
|
||||
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getAParameter() and
|
||||
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getAParameter()
|
||||
}
|
||||
|
||||
override DataFlow::Node getBaseString() {
|
||||
exists(int arg |
|
||||
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getSubstring() {
|
||||
exists(int arg |
|
||||
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override boolean getPolarity() { result = inner.getPolarity() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression of form `A.startsWith(B)`.
|
||||
*/
|
||||
|
@ -253,6 +287,41 @@ module StringOps {
|
|||
boolean getPolarity() { result = true }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a utility function (`callee`) that performs an EndsWith check (`inner`).
|
||||
*/
|
||||
private class IndirectEndsWith extends Range, DataFlow::CallNode {
|
||||
EndsWith inner;
|
||||
Function callee;
|
||||
|
||||
IndirectEndsWith() {
|
||||
inner.getEnclosingExpr() = callee.getAReturnedExpr() and
|
||||
this.getACallee() = callee and
|
||||
count(this.getACallee()) = 1 and
|
||||
count(callee.getAReturnedExpr()) = 1 and
|
||||
not this.isImprecise() and
|
||||
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getAParameter() and
|
||||
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getAParameter()
|
||||
}
|
||||
|
||||
override DataFlow::Node getBaseString() {
|
||||
exists(int arg |
|
||||
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getSubstring() {
|
||||
exists(int arg |
|
||||
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
|
||||
result = this.getArgument(arg)
|
||||
)
|
||||
}
|
||||
|
||||
override boolean getPolarity() { result = inner.getPolarity() }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A call of form `A.endsWith(B)`.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
| tst.ts:3:3:3:30 | method( ... number; | This overload of method() is unreachable, the $@ overload will always be selected. | tst.ts:2:3:2:30 | method( ... string; | previous |
|
||||
| tst.ts:6:3:6:17 | types1(): any[] | This overload of types1() is unreachable, the $@ overload will always be selected. | tst.ts:5:3:5:18 | types1<T>(): T[] | previous |
|
||||
| tst.ts:15:3:15:74 | on(even ... nction; | This overload of on() is unreachable, the $@ overload will always be selected. | tst.ts:14:3:14:74 | on(even ... nction; | previous |
|
||||
| tst.ts:21:3:21:30 | method( ... number; | This overload of method() is unreachable, the $@ overload will always be selected. | tst.ts:20:3:20:30 | method( ... string; | previous |
|
||||
| tst.ts:21:3:21:28 | bar(thi ... number; | This overload of bar() is unreachable, the $@ overload will always be selected. | tst.ts:20:3:20:28 | bar(thi ... string; | previous |
|
||||
| tst.ts:27:3:27:30 | method( ... number; | This overload of method() is unreachable, the $@ overload will always be selected. | tst.ts:26:3:26:30 | method( ... string; | previous |
|
||||
|
|
|
@ -14,6 +14,12 @@ declare class Foobar {
|
|||
on(event: string, fn?: (event?: any, ...args: any[]) => void): Function;
|
||||
on(event: string, fn?: (event?: any, ...args: any[]) => void): Function; // NOT OK.
|
||||
|
||||
foo(this: string): string;
|
||||
foo(this: number): number; // OK
|
||||
|
||||
bar(this: number): string;
|
||||
bar(this: number): number; // NOT OK
|
||||
|
||||
}
|
||||
|
||||
declare class Base {
|
||||
|
|
|
@ -1654,6 +1654,33 @@ nodes
|
|||
| normalizedPaths.js:346:19:346:22 | path |
|
||||
| normalizedPaths.js:346:19:346:22 | path |
|
||||
| normalizedPaths.js:346:19:346:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path |
|
||||
| normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| other-fs-libraries.js:9:7:9:48 | path |
|
||||
| other-fs-libraries.js:9:7:9:48 | path |
|
||||
| other-fs-libraries.js:9:7:9:48 | path |
|
||||
|
@ -4787,6 +4814,37 @@ edges
|
|||
| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) |
|
||||
| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) |
|
||||
| normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:339:13:339:46 | pathMod ... y.path) |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:356:19:356:22 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:354:7:354:27 | path | normalizedPaths.js:358:47:358:50 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:354:7:354:27 | path |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:7:358:51 | requestPath | normalizedPaths.js:363:21:363:31 | requestPath |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:21:358:51 | pathMod ... , path) | normalizedPaths.js:358:7:358:51 | requestPath |
|
||||
| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| normalizedPaths.js:358:47:358:50 | path | normalizedPaths.js:358:21:358:51 | pathMod ... , path) |
|
||||
| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path |
|
||||
| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path |
|
||||
| other-fs-libraries.js:9:7:9:48 | path | other-fs-libraries.js:11:19:11:22 | path |
|
||||
|
@ -6005,6 +6063,8 @@ edges
|
|||
| normalizedPaths.js:332:19:332:32 | normalizedPath | normalizedPaths.js:303:13:303:26 | req.query.path | normalizedPaths.js:332:19:332:32 | normalizedPath | This path depends on $@. | normalizedPaths.js:303:13:303:26 | req.query.path | a user-provided value |
|
||||
| normalizedPaths.js:341:18:341:21 | path | normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:341:18:341:21 | path | This path depends on $@. | normalizedPaths.js:339:32:339:45 | req.query.path | a user-provided value |
|
||||
| normalizedPaths.js:346:19:346:22 | path | normalizedPaths.js:339:32:339:45 | req.query.path | normalizedPaths.js:346:19:346:22 | path | This path depends on $@. | normalizedPaths.js:339:32:339:45 | req.query.path | a user-provided value |
|
||||
| normalizedPaths.js:356:19:356:22 | path | normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:356:19:356:22 | path | This path depends on $@. | normalizedPaths.js:354:14:354:27 | req.query.path | a user-provided value |
|
||||
| normalizedPaths.js:363:21:363:31 | requestPath | normalizedPaths.js:354:14:354:27 | req.query.path | normalizedPaths.js:363:21:363:31 | requestPath | This path depends on $@. | normalizedPaths.js:354:14:354:27 | req.query.path | a user-provided value |
|
||||
| other-fs-libraries.js:11:19:11:22 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:11:19:11:22 | path | This path depends on $@. | other-fs-libraries.js:9:24:9:30 | req.url | a user-provided value |
|
||||
| other-fs-libraries.js:12:27:12:30 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:12:27:12:30 | path | This path depends on $@. | other-fs-libraries.js:9:24:9:30 | req.url | a user-provided value |
|
||||
| other-fs-libraries.js:13:24:13:27 | path | other-fs-libraries.js:9:24:9:30 | req.url | other-fs-libraries.js:13:24:13:27 | path | This path depends on $@. | other-fs-libraries.js:9:24:9:30 | req.url | a user-provided value |
|
||||
|
|
|
@ -347,4 +347,27 @@ app.get('/yet-another-prefix', (req, res) => {
|
|||
return;
|
||||
}
|
||||
fs.readFileSync(path); // OK
|
||||
});
|
||||
|
||||
var rootPath = process.cwd();
|
||||
app.get('/yet-another-prefix2', (req, res) => {
|
||||
let path = req.query.path;
|
||||
|
||||
fs.readFileSync(path); // NOT OK
|
||||
|
||||
var requestPath = pathModule.join(rootPath, path);
|
||||
|
||||
var targetPath;
|
||||
if (!allowPath(requestPath, rootPath)) {
|
||||
targetPath = rootPath;
|
||||
fs.readFileSync(requestPath); // NOT OK
|
||||
} else {
|
||||
targetPath = requestPath;
|
||||
fs.readFileSync(requestPath); // OK
|
||||
}
|
||||
fs.readFileSync(targetPath); // OK
|
||||
|
||||
function allowPath(requestPath, rootPath) {
|
||||
return requestPath.indexOf(rootPath) === 0;
|
||||
}
|
||||
});
|
|
@ -1,4 +1,85 @@
|
|||
nodes
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
|
||||
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst |
|
||||
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst |
|
||||
| PrototypePollutionUtility/tests.js:3:30:3:32 | src |
|
||||
|
@ -1173,6 +1254,94 @@ nodes
|
|||
| examples/PrototypePollutionUtility_fixed.js:7:28:7:30 | key |
|
||||
| examples/PrototypePollutionUtility_fixed.js:7:28:7:30 | key |
|
||||
edges
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key | PrototypePollutionUtility/path-assignment.js:15:20:15:22 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:8:13:8:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target | PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:27 | target | PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] | PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] | PrototypePollutionUtility/path-assignment.js:13:13:13:32 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key | PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:13:29:13:31 | key | PrototypePollutionUtility/path-assignment.js:13:22:13:32 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:25:42:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key | PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:41:13:41:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:18:42:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:42:9:42:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target | PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:37 | target | PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] | PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] | PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] | PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] | PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:32:42:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:42:18:42:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key | PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:42:39:42:41 | key | PrototypePollutionUtility/path-assignment.js:42:32:42:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] | PrototypePollutionUtility/path-assignment.js:44:12:44:18 | keys[i] |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:25:59:27 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key | PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:58:13:58:25 | key |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:18:59:23 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:59:9:59:48 | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:37 | target | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] | PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] | PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] | PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] | PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:32:59:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:59:18:59:48 | target[ ... ] \|\| {} |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] | PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
|
||||
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:6:28:6:30 | dst |
|
||||
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:6:28:6:30 | dst |
|
||||
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:8:13:8:15 | dst |
|
||||
|
@ -2669,6 +2838,9 @@ edges
|
|||
| examples/PrototypePollutionUtility_fixed.js:7:28:7:30 | key | examples/PrototypePollutionUtility_fixed.js:7:24:7:31 | src[key] |
|
||||
| examples/PrototypePollutionUtility_fixed.js:7:28:7:30 | key | examples/PrototypePollutionUtility_fixed.js:7:24:7:31 | src[key] |
|
||||
#select
|
||||
| PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | target |
|
||||
| PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | target |
|
||||
| PrototypePollutionUtility/tests.js:8:13:8:15 | dst | PrototypePollutionUtility/tests.js:4:14:4:16 | key | PrototypePollutionUtility/tests.js:8:13:8:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:4:21:4:23 | src | src | PrototypePollutionUtility/tests.js:8:13:8:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:18:13:18:15 | dst | PrototypePollutionUtility/tests.js:14:30:14:32 | key | PrototypePollutionUtility/tests.js:18:13:18:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:14:17:14:19 | src | src | PrototypePollutionUtility/tests.js:18:13:18:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:36:9:36:11 | dst | PrototypePollutionUtility/tests.js:25:18:25:20 | key | PrototypePollutionUtility/tests.js:36:9:36:11 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:25:25:25:30 | source | source | PrototypePollutionUtility/tests.js:36:9:36:11 | dst | dst |
|
||||
|
@ -2677,7 +2849,7 @@ edges
|
|||
| PrototypePollutionUtility/tests.js:109:13:109:15 | dst | PrototypePollutionUtility/tests.js:102:14:102:16 | key | PrototypePollutionUtility/tests.js:109:13:109:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:102:21:102:23 | src | src | PrototypePollutionUtility/tests.js:109:13:109:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:154:13:154:15 | dst | PrototypePollutionUtility/tests.js:150:14:150:16 | key | PrototypePollutionUtility/tests.js:154:13:154:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:150:21:150:23 | src | src | PrototypePollutionUtility/tests.js:154:13:154:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:196:13:196:15 | dst | PrototypePollutionUtility/tests.js:192:19:192:25 | keys[i] | PrototypePollutionUtility/tests.js:196:13:196:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:190:28:190:30 | src | src | PrototypePollutionUtility/tests.js:196:13:196:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | PrototypePollutionUtility/tests.js:238:14:238:16 | key | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:238:21:238:24 | data | data | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | this object |
|
||||
| PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | PrototypePollutionUtility/tests.js:238:14:238:16 | key | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:238:21:238:24 | data | data | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | here |
|
||||
| PrototypePollutionUtility/tests.js:270:13:270:15 | dst | PrototypePollutionUtility/tests.js:265:19:265:26 | entry[0] | PrototypePollutionUtility/tests.js:270:13:270:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:264:20:264:22 | src | src | PrototypePollutionUtility/tests.js:270:13:270:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:280:13:280:15 | dst | PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:13:280:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:276:21:276:23 | src | src | PrototypePollutionUtility/tests.js:280:13:280:15 | dst | dst |
|
||||
| PrototypePollutionUtility/tests.js:308:17:308:19 | dst | PrototypePollutionUtility/tests.js:302:14:302:16 | key | PrototypePollutionUtility/tests.js:308:17:308:19 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:302:21:302:23 | src | src | PrototypePollutionUtility/tests.js:308:17:308:19 | dst | dst |
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
function isSafe(key) {
|
||||
return key !== "__proto__" && key !== "constructor" && key !== "prototype";
|
||||
}
|
||||
|
||||
function assignToPath(target, path, value) {
|
||||
let keys = path.split('.');
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
let key = keys[i];
|
||||
if (i < keys.length - 1) {
|
||||
if (!target[key]) {
|
||||
target[key] = {};
|
||||
}
|
||||
target = target[key];
|
||||
} else {
|
||||
target[key] = value; // NOT OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assignToPathSafe(target, path, value) {
|
||||
let keys = path.split('.');
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
let key = keys[i];
|
||||
if (!isSafe(key)) return;
|
||||
if (i < keys.length - 1) {
|
||||
if (!target[key]) {
|
||||
target[key] = {};
|
||||
}
|
||||
target = target[key];
|
||||
} else {
|
||||
target[key] = value; // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function assignToPathAfterLoop(target, path, value) {
|
||||
let keys = path.split('.');
|
||||
let i;
|
||||
for (i = 0; i < keys.length - 1; ++i) {
|
||||
let key = keys[i];
|
||||
target = target[key] = target[key] || {};
|
||||
}
|
||||
target[keys[i]] = value; // NOT OK
|
||||
}
|
||||
|
||||
function splitHelper(path, sep) {
|
||||
let parts = typeof path === 'string' ? path.split(sep || '.') : path;
|
||||
let result = [];
|
||||
result.push(...parts);
|
||||
return result;
|
||||
}
|
||||
|
||||
function assignToPathWithHelper(target, path, value, sep) {
|
||||
let keys = splitHelper(path, sep)
|
||||
let i;
|
||||
for (i = 0; i < keys.length - 1; ++i) {
|
||||
let key = keys[i];
|
||||
target = target[key] = target[key] || {};
|
||||
}
|
||||
target[keys[i]] = value; // NOT OK
|
||||
}
|
Загрузка…
Ссылка в новой задаче