mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge remote-tracking branch 'upstream/master' into mergeback-2018-10-11
This commit is contained in:
@@ -17,7 +17,7 @@ import javascript
|
||||
* Holds if `setupCall` is a call to `$sceDelegateProvider.resourceUrlWhitelist` with
|
||||
* argument `list`.
|
||||
*/
|
||||
predicate isResourceUrlWhitelist(DataFlow::MethodCallNode setupCall, DataFlow::ArrayLiteralNode list) {
|
||||
predicate isResourceUrlWhitelist(DataFlow::MethodCallNode setupCall, DataFlow::ArrayCreationNode list) {
|
||||
exists (AngularJS::ServiceReference service |
|
||||
service.getName() = "$sceDelegateProvider" and
|
||||
setupCall.asExpr() = service.getAMethodCall("resourceUrlWhitelist") and
|
||||
@@ -33,7 +33,7 @@ class ResourceUrlWhitelistEntry extends Expr {
|
||||
string pattern;
|
||||
|
||||
ResourceUrlWhitelistEntry() {
|
||||
exists (DataFlow::ArrayLiteralNode whitelist |
|
||||
exists (DataFlow::ArrayCreationNode whitelist |
|
||||
isResourceUrlWhitelist(setupCall, whitelist) and
|
||||
this = whitelist.getAnElement().asExpr() and
|
||||
this.mayHaveStringValue(pattern)
|
||||
|
||||
@@ -36,7 +36,7 @@ private predicate isBoundInMethod(MethodDeclaration method) {
|
||||
bindAll.getArgument(1).mayHaveStringValue(name)
|
||||
or
|
||||
// _.bindAll(this, [<name1>, <name2>])
|
||||
exists (DataFlow::ArrayLiteralNode names |
|
||||
exists (DataFlow::ArrayCreationNode names |
|
||||
names.flowsTo(bindAll.getArgument(1)) and
|
||||
names.getAnElement().mayHaveStringValue(name)
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name File Access data flows to Http POST/PUT
|
||||
* @description Writing data from file directly to http body or request header can be an indication to data exfiltration or unauthorized information disclosure.
|
||||
* @name File data in outbound network request
|
||||
* @description Directly sending file data in an outbound network request can indicate unauthorized information disclosure.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id js/file-access-to-http
|
||||
@@ -11,6 +11,6 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.FileAccessToHttp
|
||||
|
||||
from FileAccessToHttpDataFlow::Configuration config, DataFlow::Node src, DataFlow::Node sink
|
||||
from FileAccessToHttp::Configuration config, DataFlow::Node src, DataFlow::Node sink
|
||||
where config.hasFlow (src, sink)
|
||||
select src, "$@ flows directly to Http request body", sink, "File access"
|
||||
select sink, "$@ flows directly to outbound network request", src, "File data"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name Http response data flows to File Access
|
||||
* @description Writing data from an HTTP request directly to the file system allows arbitrary file upload and might indicate a backdoor.
|
||||
* @name User-controlled data written to file
|
||||
* @description Writing user-controlled data directly to the file system allows arbitrary file upload and might indicate a backdoor.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id js/http-to-file-access
|
||||
@@ -11,6 +11,6 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.HttpToFileAccess
|
||||
|
||||
from HttpToFileAccessFlow::Configuration configuration, DataFlow::Node src, DataFlow::Node sink
|
||||
from HttpToFileAccess::Configuration configuration, DataFlow::Node src, DataFlow::Node sink
|
||||
where configuration.hasFlow(src, sink)
|
||||
select sink, "$@ flows to file system", src, "Untrusted data received from Http response"
|
||||
select sink, "$@ flows to file system", src, "Untrusted data"
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
<p>
|
||||
|
||||
To guard against request forgery, it is advisable to avoid
|
||||
putting user input directly into a remote request. If a flexible
|
||||
remote request mechanism is required, it is recommended to maintain a
|
||||
putting user input directly into a network request. If a flexible
|
||||
network request mechanism is required, it is recommended to maintain a
|
||||
list of authorized request targets and choose from that list based on
|
||||
the user input provided.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in remote request
|
||||
* @description Sending remote requests with user-controlled data allows for request forgery attacks.
|
||||
* @name Uncontrolled data used in network request
|
||||
* @description Sending network requests with user-controlled data allows for request forgery attacks.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @precision medium
|
||||
|
||||
@@ -29,19 +29,27 @@ abstract class FileSystemAccess extends DataFlow::Node {
|
||||
/** Gets an argument to this file system access that is interpreted as a path. */
|
||||
abstract DataFlow::Node getAPathArgument();
|
||||
|
||||
/** Gets a node that represents file system access data, such as buffer the data is copied to. */
|
||||
abstract DataFlow::Node getDataNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that performs read file system access.
|
||||
* A data flow node that reads data from the file system.
|
||||
*/
|
||||
abstract class FileSystemReadAccess extends FileSystemAccess { }
|
||||
abstract class FileSystemReadAccess extends FileSystemAccess {
|
||||
|
||||
/** Gets a node that represents data from the file system. */
|
||||
abstract DataFlow::Node getADataNode();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that performs write file system access.
|
||||
* A data flow node that writes data to the file system.
|
||||
*/
|
||||
abstract class FileSystemWriteAccess extends FileSystemAccess { }
|
||||
abstract class FileSystemWriteAccess extends FileSystemAccess {
|
||||
|
||||
/** Gets a node that represents data to be written to the file system. */
|
||||
abstract DataFlow::Node getADataNode();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that contains a file name or an array of file names from the local file system.
|
||||
|
||||
@@ -303,6 +303,16 @@ class ThisExpr extends @thisexpr, Expr {
|
||||
Function getBinder() {
|
||||
result = getEnclosingFunction().getThisBinder()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function or top-level whose `this` binding this expression refers to,
|
||||
* which is the nearest enclosing non-arrow function or top-level.
|
||||
*/
|
||||
StmtContainer getBindingContainer() {
|
||||
result = getContainer().(Function).getThisBindingContainer()
|
||||
or
|
||||
result = getContainer().(TopLevel)
|
||||
}
|
||||
}
|
||||
|
||||
/** An array literal. */
|
||||
|
||||
@@ -206,6 +206,17 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
result = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function or top-level whose `this` binding a `this` expression in this function refers to,
|
||||
* which is the nearest enclosing non-arrow function or top-level.
|
||||
*/
|
||||
StmtContainer getThisBindingContainer() {
|
||||
result = getThisBinder()
|
||||
or
|
||||
not exists(getThisBinder()) and
|
||||
result = getTopLevel()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this function has a mapped `arguments` variable whose indices are aliased
|
||||
* with the function's parameters.
|
||||
|
||||
@@ -62,9 +62,9 @@ class JsonParseCall extends MethodCallExpr {
|
||||
* However, since the function could be invoked in another way, we additionally
|
||||
* still infer the ordinary abstract value.
|
||||
*/
|
||||
private class AnalyzedThisInArrayIterationFunction extends AnalyzedValueNode, DataFlow::ThisNode {
|
||||
private class AnalyzedThisInArrayIterationFunction extends AnalyzedNode, DataFlow::ThisNode {
|
||||
|
||||
AnalyzedValueNode thisSource;
|
||||
AnalyzedNode thisSource;
|
||||
|
||||
AnalyzedThisInArrayIterationFunction() {
|
||||
exists(DataFlow::MethodCallNode bindingCall, string name |
|
||||
@@ -82,7 +82,7 @@ private class AnalyzedThisInArrayIterationFunction extends AnalyzedValueNode, Da
|
||||
|
||||
override AbstractValue getALocalValue() {
|
||||
result = thisSource.getALocalValue() or
|
||||
result = AnalyzedValueNode.super.getALocalValue()
|
||||
result = AnalyzedNode.super.getALocalValue()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ private class LibraryPartialCall extends AdditionalPartialInvokeNode {
|
||||
|
||||
override predicate isPartialArgument(DataFlow::Node callback, DataFlow::Node argument, int index) {
|
||||
callback = getArgument(0) and
|
||||
exists (DataFlow::ArrayLiteralNode array |
|
||||
exists (DataFlow::ArrayCreationNode array |
|
||||
array.flowsTo(getArgument(1)) and
|
||||
argument = array.getElement(index))
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ module DataFlow {
|
||||
or TReflectiveCallNode(MethodCallExpr ce, string kind) {
|
||||
ce.getMethodName() = kind and (kind = "call" or kind = "apply")
|
||||
}
|
||||
or TThisNode(StmtContainer f) { f.(Function).getThisBinder() = f or f instanceof TopLevel }
|
||||
|
||||
/**
|
||||
* A node in the data flow graph.
|
||||
@@ -867,6 +868,13 @@ module DataFlow {
|
||||
nd = TDestructuringPatternNode(p)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Use `thisNode(StmtContainer container)` instead.
|
||||
*/
|
||||
predicate thisNode(DataFlow::Node node, StmtContainer container) {
|
||||
node = TThisNode(container)
|
||||
}
|
||||
|
||||
/**
|
||||
* A classification of flows that are not modeled, or only modeled incompletely, by
|
||||
* `DataFlowNode`:
|
||||
@@ -970,6 +978,11 @@ module DataFlow {
|
||||
pred = valueNode(defSourceNode(def)) and
|
||||
succ = TDestructuringPatternNode(def.getTarget())
|
||||
)
|
||||
or
|
||||
// flow from 'this' parameter into 'this' expressions
|
||||
exists (ThisExpr thiz |
|
||||
pred = TThisNode(thiz.getBindingContainer()) and
|
||||
succ = valueNode(thiz))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -198,16 +198,36 @@ class NewNode extends InvokeNode {
|
||||
override DataFlow::Impl::NewNodeDef impl;
|
||||
}
|
||||
|
||||
/** A data flow node corresponding to a `this` expression. */
|
||||
class ThisNode extends DataFlow::ValueNode, DataFlow::DefaultSourceNode {
|
||||
override ThisExpr astNode;
|
||||
/** A data flow node corresponding to the `this` parameter in a function or `this` at the top-level. */
|
||||
class ThisNode extends DataFlow::Node, DataFlow::DefaultSourceNode {
|
||||
ThisNode() {
|
||||
DataFlow::thisNode(this, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function whose `this` binding this expression refers to,
|
||||
* which is the nearest enclosing non-arrow function.
|
||||
*/
|
||||
FunctionNode getBinder() {
|
||||
result = DataFlow::valueNode(astNode.getBinder())
|
||||
exists (Function binder |
|
||||
DataFlow::thisNode(this, binder) and
|
||||
result = DataFlow::valueNode(binder))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function or top-level whose `this` binding this expression refers to,
|
||||
* which is the nearest enclosing non-arrow function or top-level.
|
||||
*/
|
||||
StmtContainer getBindingContainer() {
|
||||
DataFlow::thisNode(this, result)
|
||||
}
|
||||
|
||||
override string toString() { result = "this" }
|
||||
|
||||
override predicate hasLocationInfo(string filepath, int startline, int startcolumn,
|
||||
int endline, int endcolumn) {
|
||||
// Use the function entry as the location
|
||||
getBindingContainer().getEntry().getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@ class DefaultSourceNode extends SourceNode {
|
||||
astNode instanceof ObjectExpr or
|
||||
astNode instanceof ArrayExpr or
|
||||
astNode instanceof JSXNode or
|
||||
astNode instanceof ThisExpr or
|
||||
astNode instanceof GlobalVarAccess or
|
||||
astNode instanceof ExternalModuleReference
|
||||
)
|
||||
@@ -198,5 +197,7 @@ class DefaultSourceNode extends SourceNode {
|
||||
DataFlow::parameterNode(this, _)
|
||||
or
|
||||
this instanceof DataFlow::Impl::InvokeNodeDef
|
||||
or
|
||||
DataFlow::thisNode(this, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import AbstractValuesImpl
|
||||
/**
|
||||
* Flow analysis for `this` expressions inside functions.
|
||||
*/
|
||||
private abstract class AnalyzedThisExpr extends DataFlow::AnalyzedValueNode, DataFlow::ThisNode {
|
||||
private abstract class AnalyzedThisExpr extends DataFlow::AnalyzedNode, DataFlow::ThisNode {
|
||||
DataFlow::FunctionNode binder;
|
||||
|
||||
AnalyzedThisExpr() {
|
||||
@@ -29,7 +29,7 @@ private abstract class AnalyzedThisExpr extends DataFlow::AnalyzedValueNode, Dat
|
||||
*/
|
||||
private class AnalyzedThisInBoundFunction extends AnalyzedThisExpr {
|
||||
|
||||
AnalyzedValueNode thisSource;
|
||||
AnalyzedNode thisSource;
|
||||
|
||||
AnalyzedThisInBoundFunction() {
|
||||
exists(string name |
|
||||
|
||||
@@ -146,7 +146,7 @@ private DataFlow::PropWrite getAPropertyDependencyInjection(Function function) {
|
||||
*/
|
||||
private class FunctionWithInjectProperty extends InjectableFunction {
|
||||
override Function astNode;
|
||||
DataFlow::ArrayLiteralNode dependencies;
|
||||
DataFlow::ArrayCreationNode dependencies;
|
||||
|
||||
FunctionWithInjectProperty() {
|
||||
(
|
||||
|
||||
@@ -9,6 +9,10 @@ import javascript
|
||||
|
||||
/**
|
||||
* A call that performs a request to a URL.
|
||||
*
|
||||
* Example: An HTTP POST request is a client request that sends some
|
||||
* `data` to a `url`, where both the headers and the body of the request
|
||||
* contribute to the `data`.
|
||||
*/
|
||||
abstract class CustomClientRequest extends DataFlow::InvokeNode {
|
||||
|
||||
@@ -16,10 +20,20 @@ abstract class CustomClientRequest extends DataFlow::InvokeNode {
|
||||
* Gets the URL of the request.
|
||||
*/
|
||||
abstract DataFlow::Node getUrl();
|
||||
|
||||
/**
|
||||
* Gets a node that contributes to the data-part this request.
|
||||
*/
|
||||
abstract DataFlow::Node getADataNode();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that performs a request to a URL.
|
||||
*
|
||||
* Example: An HTTP POST request is client request that sends some
|
||||
* `data` to a `url`, where both the headers and the body of the request
|
||||
* contribute to the `data`.
|
||||
*/
|
||||
class ClientRequest extends DataFlow::InvokeNode {
|
||||
|
||||
@@ -35,6 +49,14 @@ class ClientRequest extends DataFlow::InvokeNode {
|
||||
DataFlow::Node getUrl() {
|
||||
result = custom.getUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that contributes to the data-part this request.
|
||||
*/
|
||||
DataFlow::Node getADataNode() {
|
||||
result = custom.getADataNode()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,6 +105,10 @@ private class RequestUrlRequest extends CustomClientRequest {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
result = getArgument(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,6 +139,10 @@ private class AxiosUrlRequest extends CustomClientRequest {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,6 +174,10 @@ private class FetchUrlRequest extends CustomClientRequest {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,6 +203,10 @@ private class GotUrlRequest extends CustomClientRequest {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,4 +229,8 @@ private class SuperAgentUrlRequest extends CustomClientRequest {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ module Electron {
|
||||
result = getOptionArgument(0, "url")
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,6 +82,10 @@ module Electron {
|
||||
result = getOptionArgument(0, "url")
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -824,7 +824,7 @@ module Express {
|
||||
}
|
||||
|
||||
/** A call to `response.sendFile`, considered as a file system access. */
|
||||
private class ResponseSendFileAsFileSystemAccess extends FileSystemAccess, DataFlow::ValueNode {
|
||||
private class ResponseSendFileAsFileSystemAccess extends FileSystemReadAccess, DataFlow::ValueNode {
|
||||
override MethodCallExpr astNode;
|
||||
|
||||
ResponseSendFileAsFileSystemAccess() {
|
||||
@@ -832,8 +832,8 @@ module Express {
|
||||
asExpr().(MethodCallExpr).calls(any(ResponseExpr res), name))
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
result = DataFlow::valueNode(astNode)
|
||||
override DataFlow::Node getADataNode() {
|
||||
none()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
@@ -891,7 +891,7 @@ module Express {
|
||||
getMethodName() = methodName and
|
||||
exists (DataFlow::ValueNode arg |
|
||||
arg = getAnArgument() |
|
||||
exists (DataFlow::ArrayLiteralNode array |
|
||||
exists (DataFlow::ArrayCreationNode array |
|
||||
array.flowsTo(arg) and
|
||||
routeHandlerArg = array.getAnElement()
|
||||
) or
|
||||
|
||||
@@ -144,8 +144,8 @@ module ExpressLibraries {
|
||||
|
||||
override DataFlow::Node getASecretKey() {
|
||||
exists (DataFlow::Node secret | secret = getOption("secret") |
|
||||
if exists(DataFlow::ArrayLiteralNode arr | arr.flowsTo(secret)) then
|
||||
result = any (DataFlow::ArrayLiteralNode arr | arr.flowsTo(secret)).getAnElement()
|
||||
if exists(DataFlow::ArrayCreationNode arr | arr.flowsTo(secret)) then
|
||||
result = any (DataFlow::ArrayCreationNode arr | arr.flowsTo(secret)).getAnElement()
|
||||
else
|
||||
result = secret
|
||||
)
|
||||
@@ -182,8 +182,8 @@ module ExpressLibraries {
|
||||
|
||||
override DataFlow::Node getASecretKey() {
|
||||
exists (DataFlow::Node arg0 | arg0 = getArgument(0) |
|
||||
if exists(DataFlow::ArrayLiteralNode arr | arr.flowsTo(arg0)) then
|
||||
result = any (DataFlow::ArrayLiteralNode arr | arr.flowsTo(arg0)).getAnElement()
|
||||
if exists(DataFlow::ArrayCreationNode arr | arr.flowsTo(arg0)) then
|
||||
result = any (DataFlow::ArrayCreationNode arr | arr.flowsTo(arg0)).getAnElement()
|
||||
else
|
||||
result = arg0
|
||||
)
|
||||
@@ -220,7 +220,7 @@ module ExpressLibraries {
|
||||
|
||||
override DataFlow::Node getASecretKey() {
|
||||
result = getOption("secret") or
|
||||
exists (DataFlow::ArrayLiteralNode keys |
|
||||
exists (DataFlow::ArrayCreationNode keys |
|
||||
keys.flowsTo(getOption("keys")) and
|
||||
result = keys.getAnElement()
|
||||
)
|
||||
|
||||
@@ -132,11 +132,6 @@ module HTTP {
|
||||
result = "http" or result = "https"
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression whose value is sent as (part of) the body of an HTTP request (POST, PUT).
|
||||
*/
|
||||
abstract class RequestBody extends DataFlow::Node {}
|
||||
|
||||
/**
|
||||
* An expression whose value is sent as (part of) the body of an HTTP response.
|
||||
*/
|
||||
|
||||
@@ -27,9 +27,9 @@ module LodashUnderscore {
|
||||
* However, since the function could be invoked in another way, we additionally
|
||||
* still infer the ordinary abstract value.
|
||||
*/
|
||||
private class AnalyzedThisInBoundCallback extends AnalyzedValueNode, DataFlow::ThisNode {
|
||||
private class AnalyzedThisInBoundCallback extends AnalyzedNode, DataFlow::ThisNode {
|
||||
|
||||
AnalyzedValueNode thisSource;
|
||||
AnalyzedNode thisSource;
|
||||
|
||||
AnalyzedThisInBoundCallback() {
|
||||
exists(DataFlow::CallNode bindingCall, string binderName, int callbackIndex, int contextIndex, int argumentCount |
|
||||
@@ -128,7 +128,7 @@ private class AnalyzedThisInBoundCallback extends AnalyzedValueNode, DataFlow::T
|
||||
|
||||
override AbstractValue getALocalValue() {
|
||||
result = thisSource.getALocalValue() or
|
||||
result = AnalyzedValueNode.super.getALocalValue()
|
||||
result = AnalyzedNode.super.getALocalValue()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ module NodeJSLib {
|
||||
*
|
||||
* We determine this by looking for an externs declaration for
|
||||
* `fs.methodName` where the `i`th parameter's name is `data` or
|
||||
* `buffer` or a 'callback'.
|
||||
* `buffer` or a `callback`.
|
||||
*/
|
||||
private predicate fsDataParam(string methodName, int i, string n) {
|
||||
exists (ExternalMemberDecl decl, Function f, JSDocParamTag p |
|
||||
@@ -401,160 +401,138 @@ module NodeJSLib {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A call to a method from module `fs`, `graceful-fs` or `fs-extra`.
|
||||
*/
|
||||
private class NodeJSFileSystemAccessCall extends FileSystemAccess, DataFlow::CallNode {
|
||||
private class NodeJSFileSystemAccess extends FileSystemAccess, DataFlow::CallNode {
|
||||
string methodName;
|
||||
|
||||
NodeJSFileSystemAccessCall() {
|
||||
NodeJSFileSystemAccess() {
|
||||
this = fsModuleMember(methodName).getACall()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the called method.
|
||||
*/
|
||||
string getMethodName() {
|
||||
result = methodName
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
(
|
||||
methodName = "readFileSync" and
|
||||
result = this
|
||||
)
|
||||
or
|
||||
exists (int i, string paramName | fsDataParam(methodName, i, paramName) |
|
||||
(
|
||||
paramName = "callback" and
|
||||
exists (DataFlow::ParameterNode p, string n |
|
||||
p = getCallback(i).getAParameter() and
|
||||
n = p.getName().toLowerCase() and
|
||||
result = p |
|
||||
n = "data" or n = "buffer" or n = "string"
|
||||
)
|
||||
)
|
||||
or
|
||||
result = getArgument(i))
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
exists (int i | fsFileParam(methodName, i) |
|
||||
result = getArgument(i))
|
||||
}
|
||||
}
|
||||
|
||||
/** Only NodeJSSystemFileAccessCalls that write data to 'fs' */
|
||||
private class NodeJSFileSystemAccessWriteCall extends FileSystemWriteAccess, NodeJSFileSystemAccessCall {
|
||||
NodeJSFileSystemAccessWriteCall () {
|
||||
this.getMethodName() = "appendFile" or
|
||||
this.getMethodName() = "appendFileSync" or
|
||||
this.getMethodName() = "write" or
|
||||
this.getMethodName() = "writeFile" or
|
||||
this.getMethodName() = "writeFileSync" or
|
||||
this.getMethodName() = "writeSync"
|
||||
}
|
||||
}
|
||||
/** A write to the file system. */
|
||||
private class NodeJSFileSystemAccessWrite extends FileSystemWriteAccess, NodeJSFileSystemAccess {
|
||||
NodeJSFileSystemAccessWrite () {
|
||||
methodName = "appendFile" or
|
||||
methodName = "appendFileSync" or
|
||||
methodName = "write" or
|
||||
methodName = "writeFile" or
|
||||
methodName = "writeFileSync" or
|
||||
methodName = "writeSync"
|
||||
}
|
||||
|
||||
/** Only NodeJSSystemFileAccessCalls that read data from 'fs' */
|
||||
private class NodeJSFileSystemAccessReadCall extends FileSystemReadAccess, NodeJSFileSystemAccessCall {
|
||||
NodeJSFileSystemAccessReadCall () {
|
||||
this.getMethodName() = "read" or
|
||||
this.getMethodName() = "readSync" or
|
||||
this.getMethodName() = "readFile" or
|
||||
this.getMethodName() = "readFileSync"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to write corresponds to a pattern where file stream is open first with 'createWriteStream', followed by 'write' or 'end' call
|
||||
*/
|
||||
private class NodeJSFileSystemWrite extends FileSystemWriteAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccessCall init;
|
||||
|
||||
NodeJSFileSystemWrite() {
|
||||
exists (NodeJSFileSystemAccessCall n |
|
||||
n.getCalleeName() = "createWriteStream" and init = n |
|
||||
this = n.getAMemberCall("write") or
|
||||
this = n.getAMemberCall("end")
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
result = this.getArgument(0)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = init.getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to read corresponds to a pattern where file stream is open first with createReadStream, followed by 'read' call
|
||||
*/
|
||||
private class NodeJSFileSystemRead extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccessCall init;
|
||||
|
||||
NodeJSFileSystemRead() {
|
||||
exists (NodeJSFileSystemAccessCall n |
|
||||
n.getCalleeName() = "createReadStream" and init = n |
|
||||
this = n.getAMemberCall("read")
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
result = this
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = init.getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to read corresponds to a pattern where file stream is open first with createReadStream, followed by 'pipe' call
|
||||
*/
|
||||
private class NodeJSFileSystemPipe extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccessCall init;
|
||||
|
||||
NodeJSFileSystemPipe() {
|
||||
exists (NodeJSFileSystemAccessCall n |
|
||||
n.getCalleeName() = "createReadStream" and init = n |
|
||||
this = n.getAMemberCall("pipe")
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
result = this.getArgument(0)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = init.getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An 'on' event where data comes in as a parameter (usage: readstream.on('data', chunk))
|
||||
*/
|
||||
private class NodeJSFileSystemReadDataEvent extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccessCall init;
|
||||
|
||||
NodeJSFileSystemReadDataEvent() {
|
||||
exists(NodeJSFileSystemAccessCall n |
|
||||
n.getCalleeName() = "createReadStream" and init = n |
|
||||
this = n.getAMethodCall("on") and
|
||||
this.getArgument(0).mayHaveStringValue("data")
|
||||
override DataFlow::Node getADataNode() {
|
||||
exists (int i, string paramName |
|
||||
fsDataParam(methodName, i, paramName) |
|
||||
if paramName = "callback" then
|
||||
exists (DataFlow::ParameterNode p |
|
||||
p = getCallback(i).getAParameter() and
|
||||
p.getName().regexpMatch("(?i)data|buffer|string") and
|
||||
result = p
|
||||
)
|
||||
else
|
||||
result = getArgument(i)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDataNode() {
|
||||
result = this.getCallback(1).getParameter(0)
|
||||
}
|
||||
|
||||
/** A file system read. */
|
||||
private class NodeJSFileSystemAccessRead extends FileSystemReadAccess, NodeJSFileSystemAccess {
|
||||
NodeJSFileSystemAccessRead () {
|
||||
methodName = "read" or
|
||||
methodName = "readSync" or
|
||||
methodName = "readFile" or
|
||||
methodName = "readFileSync"
|
||||
}
|
||||
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
if methodName.regexpMatch(".*Sync") then
|
||||
result = this
|
||||
else
|
||||
exists (int i, string paramName |
|
||||
fsDataParam(methodName, i, paramName) |
|
||||
if paramName = "callback" then
|
||||
exists (DataFlow::ParameterNode p |
|
||||
p = getCallback(i).getAParameter() and
|
||||
p.getName().regexpMatch("(?i)data|buffer|string") and
|
||||
result = p
|
||||
)
|
||||
else
|
||||
result = getArgument(i)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to the file system, using a stream.
|
||||
*/
|
||||
private class FileStreamWrite extends FileSystemWriteAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccess stream;
|
||||
|
||||
FileStreamWrite() {
|
||||
stream.getMethodName() = "createWriteStream" and
|
||||
exists (string method |
|
||||
method = "write" or
|
||||
method = "end" |
|
||||
this = stream.getAMemberCall(method)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
result = getArgument(0)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = init.getAPathArgument()
|
||||
result = stream.getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A read from the file system using a stream.
|
||||
*/
|
||||
private class FileStreamRead extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
|
||||
NodeJSFileSystemAccess stream;
|
||||
|
||||
string method;
|
||||
|
||||
FileStreamRead() {
|
||||
stream.getMethodName() = "createReadStream" and
|
||||
this = stream.getAMemberCall(method) and
|
||||
(method = "read" or method = "pipe" or method = "on")
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
method = "read" and
|
||||
result = this
|
||||
or
|
||||
method = "pipe" and
|
||||
result = getArgument(0)
|
||||
or
|
||||
method = "on" and
|
||||
getArgument(0).mayHaveStringValue("data") and
|
||||
result = getCallback(1).getParameter(0)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = stream.getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,6 +739,10 @@ module NodeJSLib {
|
||||
result = url
|
||||
}
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
result = getAMethodCall("write").getArgument(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,18 +776,6 @@ module NodeJSLib {
|
||||
result = "http.request data parameter"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to client request.write () method, can be used to write body to a HTTP or HTTPS POST/PUT request,
|
||||
* or request option (like headers, cookies, even url)
|
||||
*/
|
||||
class HttpRequestWriteArgument extends HTTP::RequestBody, DataFlow::Node {
|
||||
HttpRequestWriteArgument () {
|
||||
exists(CustomClientRequest req |
|
||||
this = req.getAMethodCall("write").getArgument(0) or
|
||||
this = req.getArgument(0))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that is registered as a callback for an HTTP or HTTPS request made by a Node.js process, for example the function `handler` in `http.request(url).on(message, handler)`.
|
||||
|
||||
@@ -52,10 +52,20 @@ abstract class ReactComponent extends ASTNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `this` access in an instance method of this component.
|
||||
* Gets the `this` node in an instance method of this component.
|
||||
*/
|
||||
DataFlow::SourceNode getAThisNode() {
|
||||
result.(DataFlow::ThisNode).getBinder().getFunction() = getInstanceMethod(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `this` node in an instance method of this component.
|
||||
*
|
||||
* DEPRECATED: Use `getAThisNode` instead.
|
||||
*/
|
||||
deprecated
|
||||
DataFlow::SourceNode getAThisAccess() {
|
||||
result.asExpr().(ThisExpr).getBinder() = getInstanceMethod(_)
|
||||
result = getAThisNode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -515,9 +525,9 @@ private class FactoryDefinition extends ReactElementDefinition {
|
||||
* However, since the function could be invoked in another way, we additionally
|
||||
* still infer the ordinary abstract value.
|
||||
*/
|
||||
private class AnalyzedThisInBoundCallback extends AnalyzedValueNode, DataFlow::ThisNode {
|
||||
private class AnalyzedThisInBoundCallback extends AnalyzedNode, DataFlow::ThisNode {
|
||||
|
||||
AnalyzedValueNode thisSource;
|
||||
AnalyzedNode thisSource;
|
||||
|
||||
AnalyzedThisInBoundCallback() {
|
||||
exists(DataFlow::CallNode bindingCall, string binderName |
|
||||
@@ -533,7 +543,7 @@ private class AnalyzedThisInBoundCallback extends AnalyzedValueNode, DataFlow::T
|
||||
|
||||
override AbstractValue getALocalValue() {
|
||||
result = thisSource.getALocalValue() or
|
||||
result = AnalyzedValueNode.super.getALocalValue()
|
||||
result = AnalyzedNode.super.getALocalValue()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,13 +44,5 @@ module Request {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// using 'request' library to make http 'POST' and 'PUT' requests with message body.
|
||||
private class RequestPostBody extends HTTP::RequestBody {
|
||||
RequestPostBody () {
|
||||
this = DataFlow::moduleMember("request", "post").getACall().getArgument(1) or
|
||||
this = DataFlow::moduleImport("request").getAnInvocation().getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,7 +75,7 @@ module CommandInjection {
|
||||
ArgumentListTracking() { this = "ArgumentListTracking" }
|
||||
|
||||
override predicate isSource(DataFlow::Node nd) {
|
||||
nd instanceof DataFlow::ArrayLiteralNode
|
||||
nd instanceof DataFlow::ArrayCreationNode
|
||||
or
|
||||
exists (StringLiteral shell | shellCmd(shell, _) |
|
||||
nd = DataFlow::valueNode(shell)
|
||||
@@ -125,7 +125,7 @@ module CommandInjection {
|
||||
* we want to report the `spawn` call as the sink, so we bind it to `sys`.
|
||||
*/
|
||||
private predicate indirectCommandInjection(DataFlow::Node sink, SystemCommandExecution sys) {
|
||||
exists (ArgumentListTracking cfg, DataFlow::ArrayLiteralNode args,
|
||||
exists (ArgumentListTracking cfg, DataFlow::ArrayCreationNode args,
|
||||
StringLiteral shell, string dashC |
|
||||
shellCmd(shell, dashC) and
|
||||
cfg.hasFlow(DataFlow::valueNode(shell), sys.getACommandArgument()) and
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
/**
|
||||
* Provides Taint tracking configuration for reasoning about file access taint flow to http post body
|
||||
/**
|
||||
* Provides a taint tracking configuration for reasoning about file data in outbound network requests.
|
||||
*/
|
||||
import javascript
|
||||
import semmle.javascript.frameworks.HTTP
|
||||
import semmle.javascript.security.dataflow.RemoteFlowSources
|
||||
|
||||
module FileAccessToHttp {
|
||||
|
||||
module FileAccessToHttpDataFlow {
|
||||
/**
|
||||
* A data flow source for reasoning about file access to http post body flow vulnerabilities.
|
||||
* A data flow source for file data in outbound network requests.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for reasoning about file access to http post body flow vulnerabilities.
|
||||
* A data flow sink for file data in outbound network requests.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for reasoning about file access to http post body flow vulnerabilities.
|
||||
* A sanitizer for file data in outbound network requests.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for reasoning about file access to http post body flow vulnerabilities.
|
||||
* A taint tracking configuration for file data in outbound network requests.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "FileAccessToHttpDataFlow" }
|
||||
Configuration() {
|
||||
this = "FileAccessToHttp"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof Source
|
||||
@@ -38,14 +41,9 @@ module FileAccessToHttpDataFlow {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
/** additional taint step that taints an object wrapping a source */
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
(
|
||||
pred = DataFlow::valueNode(_) or
|
||||
pred = DataFlow::parameterNode(_) or
|
||||
pred instanceof DataFlow::PropRead
|
||||
) and
|
||||
// taint entire object on property write
|
||||
exists (DataFlow::PropWrite pwr |
|
||||
succ = pwr.getBase() and
|
||||
pred = pwr.getRhs()
|
||||
@@ -53,19 +51,26 @@ module FileAccessToHttpDataFlow {
|
||||
}
|
||||
}
|
||||
|
||||
/** A source is a file access parameter, as in readFromFile(buffer). */
|
||||
/**
|
||||
* A file access parameter, considered as a flow source for file data in outbound network requests.
|
||||
*/
|
||||
private class FileAccessArgumentAsSource extends Source {
|
||||
FileAccessArgumentAsSource() {
|
||||
exists(FileSystemReadAccess src |
|
||||
this = src.getDataNode().getALocalSource()
|
||||
this = src.getADataNode().getALocalSource()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Sink is any parameter or argument that evaluates to a parameter ot a function or call that sets Http Body on a request */
|
||||
private class HttpRequestBodyAsSink extends Sink {
|
||||
HttpRequestBodyAsSink () {
|
||||
this instanceof HTTP::RequestBody
|
||||
/**
|
||||
* The URL or data of a client request, considered as a flow source for file data in outbound network requests.
|
||||
*/
|
||||
private class ClientRequestUrlOrDataAsSink extends Sink {
|
||||
ClientRequestUrlOrDataAsSink () {
|
||||
exists (ClientRequest req |
|
||||
this = req.getUrl() or
|
||||
this = req.getADataNode()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,33 @@
|
||||
/**
|
||||
* Provides taint tracking configuration for reasoning about files created from untrusted http downloads.
|
||||
/**
|
||||
* Provides a taint tracking configuration for reasoning about writing user-controlled data to files.
|
||||
*/
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.RemoteFlowSources
|
||||
|
||||
module HttpToFileAccessFlow {
|
||||
module HttpToFileAccess {
|
||||
|
||||
/**
|
||||
* A data flow source from untrusted http request to file access taint tracking configuration.
|
||||
* A data flow source for writing user-controlled data to files.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for untrusted http request to file access taint tracking configuration.
|
||||
* A data flow sink for writing user-controlled data to files.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for untrusted http request to file access taint tracking configuration.
|
||||
* A sanitizer for writing user-controlled data to files.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for reasoning about file access from untrusted http response body.
|
||||
* A taint tracking configuration for writing user-controlled data to files.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "HttpToFileAccessFlow" }
|
||||
Configuration() {
|
||||
this = "HttpToFileAccess"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof Source
|
||||
@@ -39,17 +42,17 @@ module HttpToFileAccessFlow {
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
/** A source of remote data, considered as a flow source for untrusted http data to file system access. */
|
||||
|
||||
/** A source of remote user input, considered as a flow source for writing user-controlled data to files. */
|
||||
class RemoteFlowSourceAsSource extends Source {
|
||||
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
|
||||
|
||||
/** A sink that represents file access method (write, append) argument */
|
||||
class FileAccessAsSink extends Sink {
|
||||
FileAccessAsSink () {
|
||||
exists(FileSystemWriteAccess src |
|
||||
this = src.getDataNode()
|
||||
this = src.getADataNode()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
| tst.js:37:5:42:1 | o | tst.js:83:23:83:23 | o |
|
||||
| tst.js:37:5:42:1 | o | tst.js:85:23:85:23 | o |
|
||||
| tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | tst.js:37:5:42:1 | o |
|
||||
| tst.js:39:4:39:3 | this | tst.js:40:5:40:8 | this |
|
||||
| tst.js:46:10:46:11 | "" | tst.js:46:1:46:11 | global = "" |
|
||||
| tst.js:49:1:54:1 | A | tst.js:55:1:55:1 | A |
|
||||
| tst.js:49:1:54:1 | class A ... `\\n }\\n} | tst.js:49:1:54:1 | A |
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
| eval.js:1:1:1:0 | this |
|
||||
| eval.js:1:1:1:0 | this |
|
||||
| eval.js:1:1:5:1 | functio ... eval`\\n} |
|
||||
| eval.js:3:3:3:6 | eval |
|
||||
| eval.js:3:3:3:16 | eval("x = 23") |
|
||||
| sources.js:1:1:1:0 | this |
|
||||
| sources.js:1:1:1:12 | new (x => x) |
|
||||
| sources.js:1:6:1:6 | x |
|
||||
| sources.js:1:6:1:11 | x => x |
|
||||
| sources.js:3:1:5:6 | (functi ... \\n})(23) |
|
||||
| sources.js:3:2:3:1 | this |
|
||||
| sources.js:3:2:5:1 | functio ... x+19;\\n} |
|
||||
| sources.js:3:11:3:11 | x |
|
||||
| tst.js:1:1:1:0 | this |
|
||||
| tst.js:1:10:1:11 | fs |
|
||||
| tst.js:16:1:20:9 | (functi ... ("arg") |
|
||||
| tst.js:16:2:16:1 | this |
|
||||
| tst.js:16:2:20:1 | functio ... n "";\\n} |
|
||||
| tst.js:16:13:16:13 | a |
|
||||
| tst.js:17:7:17:10 | Math |
|
||||
@@ -17,11 +23,12 @@
|
||||
| tst.js:22:7:22:18 | readFileSync |
|
||||
| tst.js:28:1:30:3 | (() =>\\n ... les\\n)() |
|
||||
| tst.js:28:2:29:3 | () =>\\n x |
|
||||
| tst.js:32:1:32:0 | this |
|
||||
| tst.js:32:1:34:1 | functio ... ables\\n} |
|
||||
| tst.js:35:1:35:7 | g(true) |
|
||||
| tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} |
|
||||
| tst.js:39:4:39:3 | this |
|
||||
| tst.js:39:4:41:3 | () {\\n this;\\n } |
|
||||
| tst.js:40:5:40:8 | this |
|
||||
| tst.js:43:1:43:3 | o.x |
|
||||
| tst.js:44:1:44:3 | o.m |
|
||||
| tst.js:44:1:44:5 | o.m() |
|
||||
@@ -29,18 +36,22 @@
|
||||
| tst.js:47:1:47:6 | global |
|
||||
| tst.js:49:1:54:1 | class A ... `\\n }\\n} |
|
||||
| tst.js:49:17:49:17 | B |
|
||||
| tst.js:50:14:50:13 | this |
|
||||
| tst.js:50:14:53:3 | () {\\n ... et`\\n } |
|
||||
| tst.js:51:5:51:13 | super(42) |
|
||||
| tst.js:58:1:58:3 | tag |
|
||||
| tst.js:61:3:61:5 | o.m |
|
||||
| tst.js:64:1:64:0 | this |
|
||||
| tst.js:64:1:67:1 | functio ... lysed\\n} |
|
||||
| tst.js:68:12:68:14 | h() |
|
||||
| tst.js:69:1:69:9 | iter.next |
|
||||
| tst.js:69:1:69:13 | iter.next(23) |
|
||||
| tst.js:71:1:71:0 | this |
|
||||
| tst.js:71:1:73:1 | async f ... lysed\\n} |
|
||||
| tst.js:72:9:72:9 | p |
|
||||
| tst.js:72:9:72:11 | p() |
|
||||
| tst.js:87:1:96:2 | (functi ... r: 0\\n}) |
|
||||
| tst.js:87:2:87:1 | this |
|
||||
| tst.js:87:2:92:1 | functio ... + z;\\n} |
|
||||
| tst.js:87:11:87:24 | { p: x, ...o } |
|
||||
| tst.js:87:13:87:16 | p: x |
|
||||
@@ -49,6 +60,7 @@
|
||||
| tst.js:90:6:90:9 | r: z |
|
||||
| tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} |
|
||||
| tst.js:98:1:103:17 | (functi ... 3, 0 ]) |
|
||||
| tst.js:98:2:98:1 | this |
|
||||
| tst.js:98:2:103:1 | functio ... + z;\\n} |
|
||||
| tst.js:98:11:98:24 | [ x, ...rest ] |
|
||||
| tst.js:98:13:98:13 | x |
|
||||
@@ -56,7 +68,9 @@
|
||||
| tst.js:99:9:99:9 | y |
|
||||
| tst.js:101:7:101:7 | z |
|
||||
| tst.js:103:4:103:16 | [ 19, 23, 0 ] |
|
||||
| tst.ts:1:1:1:0 | this |
|
||||
| tst.ts:3:3:3:8 | setX() |
|
||||
| tst.ts:7:1:7:0 | this |
|
||||
| tst.ts:7:1:9:1 | functio ... = 23;\\n} |
|
||||
| tst.ts:8:3:8:5 | A.x |
|
||||
| tst.ts:11:11:11:13 | A.x |
|
||||
@@ -65,3 +79,4 @@
|
||||
| tst.ts:13:39:13:38 | (...arg ... rgs); } |
|
||||
| tst.ts:13:39:13:38 | args |
|
||||
| tst.ts:13:39:13:38 | super(...args) |
|
||||
| tst.ts:13:39:13:38 | this |
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
| tst2.js:1:1:1:0 | this |
|
||||
| tst2.js:1:9:1:25 | require("global") |
|
||||
| tst2.js:3:1:3:24 | require ... indow") |
|
||||
| tst2.js:7:1:7:6 | global |
|
||||
| tst2.js:8:1:8:6 | global |
|
||||
| tst2.js:9:1:9:4 | this |
|
||||
| tst.js:1:1:1:0 | this |
|
||||
| tst.js:1:1:1:6 | window |
|
||||
| tst.js:2:1:2:4 | this |
|
||||
| tst.js:3:1:3:6 | window |
|
||||
| tst.js:4:1:4:6 | window |
|
||||
| tst.js:4:1:4:13 | window.window |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| tst.js:1:1:1:0 | this | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:1:1:1:0 | this | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:14:5:14:11 | console | tst.js:14:5:14:15 | console.log |
|
||||
| tst.js:17:5:17:11 | console | tst.js:17:5:17:15 | console.log |
|
||||
| tst.js:23:15:23:18 | this | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:23:15:23:29 | this.someMethod | tst.js:23:15:23:34 | this.someMethod.bind |
|
||||
| tst.js:24:36:24:39 | this | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:24:36:24:45 | this.state | tst.js:24:36:24:50 | this.state.name |
|
||||
| tst.js:34:6:34:7 | vv | tst.js:34:6:34:10 | vv.pp |
|
||||
| tst.js:35:6:35:8 | vvv | tst.js:35:6:35:12 | vvv.ppp |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| tst.js:1:1:1:0 | this | someMethod | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:1:1:1:0 | this | state | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:14:5:14:11 | console | log | tst.js:14:5:14:15 | console.log |
|
||||
| tst.js:17:5:17:11 | console | log | tst.js:17:5:17:15 | console.log |
|
||||
| tst.js:23:15:23:18 | this | someMethod | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:23:15:23:29 | this.someMethod | bind | tst.js:23:15:23:34 | this.someMethod.bind |
|
||||
| tst.js:24:36:24:39 | this | state | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:24:36:24:45 | this.state | name | tst.js:24:36:24:50 | this.state.name |
|
||||
| tst.js:34:6:34:7 | vv | pp | tst.js:34:6:34:10 | vv.pp |
|
||||
| tst.js:35:6:35:8 | vvv | ppp | tst.js:35:6:35:12 | vvv.ppp |
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
| tst.js:1:1:1:0 | this | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:1:1:1:0 | this | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:3:5:3:8 | x: 4 |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:4:5:6:5 | func: f ... ;\\n } |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:7:5:9:5 | f() {\\n ... ;\\n } |
|
||||
@@ -5,10 +7,8 @@
|
||||
| tst.js:14:5:14:11 | console | tst.js:14:5:14:15 | console.log |
|
||||
| tst.js:17:5:17:11 | console | tst.js:17:5:17:15 | console.log |
|
||||
| tst.js:21:1:21:1 | C | tst.js:21:1:21:6 | C.prop |
|
||||
| tst.js:23:15:23:18 | this | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:23:15:23:29 | this.someMethod | tst.js:23:15:23:34 | this.someMethod.bind |
|
||||
| tst.js:24:8:24:57 | <div on ... }</div> | tst.js:24:13:24:27 | onClick={click} |
|
||||
| tst.js:24:36:24:39 | this | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:24:36:24:45 | this.state | tst.js:24:36:24:50 | this.state.name |
|
||||
| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:27:3:27:26 | get x() ... null; } |
|
||||
| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:28:3:28:13 | set y(v) {} |
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
| tst.js:1:1:1:0 | this | someMethod | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:1:1:1:0 | this | state | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | f | tst.js:7:5:9:5 | f() {\\n ... ;\\n } |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | func | tst.js:4:5:6:5 | func: f ... ;\\n } |
|
||||
| tst.js:2:11:10:1 | {\\n x ... }\\n} | x | tst.js:3:5:3:8 | x: 4 |
|
||||
@@ -5,10 +7,8 @@
|
||||
| tst.js:14:5:14:11 | console | log | tst.js:14:5:14:15 | console.log |
|
||||
| tst.js:17:5:17:11 | console | log | tst.js:17:5:17:15 | console.log |
|
||||
| tst.js:21:1:21:1 | C | prop | tst.js:21:1:21:6 | C.prop |
|
||||
| tst.js:23:15:23:18 | this | someMethod | tst.js:23:15:23:29 | this.someMethod |
|
||||
| tst.js:23:15:23:29 | this.someMethod | bind | tst.js:23:15:23:34 | this.someMethod.bind |
|
||||
| tst.js:24:8:24:57 | <div on ... }</div> | onClick | tst.js:24:13:24:27 | onClick={click} |
|
||||
| tst.js:24:36:24:39 | this | state | tst.js:24:36:24:45 | this.state |
|
||||
| tst.js:24:36:24:45 | this.state | name | tst.js:24:36:24:50 | this.state.name |
|
||||
| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | x | tst.js:27:3:27:26 | get x() ... null; } |
|
||||
| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | y | tst.js:28:3:28:13 | set y(v) {} |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value |
|
||||
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:41:10:41:18 | id(taint) |
|
||||
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:51:14:51:14 | x |
|
||||
| thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field |
|
||||
| thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 |
|
||||
| tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x |
|
||||
| tst.js:2:13:2:20 | source() | tst.js:5:10:5:22 | "/" + x + "!" |
|
||||
| tst.js:2:13:2:20 | source() | tst.js:14:10:14:17 | x.sort() |
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class C {
|
||||
foo() {
|
||||
let obj = {};
|
||||
obj.field = source();
|
||||
sink(obj.field); // NOT OK - tainted
|
||||
|
||||
this.field2 = source();
|
||||
sink(this.field2); // NOT OK - tainted
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,42 @@
|
||||
| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} |
|
||||
| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:3:11:3:10 | this |
|
||||
| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:4:24:4:27 | this |
|
||||
| es5.js:1:31:11:1 | {\\n dis ... ;\\n }\\n} | es5.js:6:20:6:19 | this |
|
||||
| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} |
|
||||
| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:19:11:19:10 | this |
|
||||
| es5.js:18:33:22:1 | {\\n ren ... ;\\n }\\n} | es5.js:20:24:20:27 | this |
|
||||
| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:1:37:1:36 | this |
|
||||
| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:2:9:2:8 | this |
|
||||
| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:3:24:3:27 | this |
|
||||
| es6.js:1:1:8:1 | class H ... ;\\n }\\n} | es6.js:5:14:5:13 | this |
|
||||
| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:15:16:15:15 | this |
|
||||
| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:16:9:16:12 | this |
|
||||
| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:17:9:17:12 | this |
|
||||
| es6.js:14:1:20:1 | class H ... }\\n} | es6.js:18:9:18:12 | this |
|
||||
| namedImport.js:3:1:3:28 | class C ... nent {} | namedImport.js:3:27:3:26 | this |
|
||||
| namedImport.js:5:1:5:20 | class D extends C {} | namedImport.js:5:19:5:18 | this |
|
||||
| plainfn.js:1:1:3:1 | functio ... div>;\\n} | plainfn.js:1:1:1:0 | this |
|
||||
| plainfn.js:5:1:7:1 | functio ... iv");\\n} | plainfn.js:5:1:5:0 | this |
|
||||
| plainfn.js:9:1:12:1 | functio ... rn x;\\n} | plainfn.js:9:1:9:0 | this |
|
||||
| plainfn.js:20:1:24:1 | functio ... n 42;\\n} | plainfn.js:20:1:20:0 | this |
|
||||
| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:1:38:1:37 | this |
|
||||
| preact.js:1:1:7:1 | class H ... }\\n} | preact.js:2:11:2:10 | this |
|
||||
| preact.js:9:1:11:1 | class H ... nt {\\n\\n} | preact.js:9:38:9:37 | this |
|
||||
| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:1:31:1:30 | this |
|
||||
| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:2:11:2:10 | this |
|
||||
| probably-a-component.js:1:1:6:1 | class H ... }\\n} | probably-a-component.js:3:9:3:12 | this |
|
||||
| props.js:2:5:3:5 | class C ... {\\n } | props.js:2:37:2:36 | this |
|
||||
| props.js:2:5:3:5 | class C ... {\\n } | props.js:9:5:9:55 | new C({ ... ctor"}) |
|
||||
| props.js:13:31:17:5 | {\\n ... }\\n } | props.js:13:31:17:5 | {\\n ... }\\n } |
|
||||
| props.js:13:31:17:5 | {\\n ... }\\n } | props.js:14:24:14:23 | this |
|
||||
| props.js:26:5:28:5 | functio ... ;\\n } | props.js:26:5:26:4 | this |
|
||||
| props.js:26:5:28:5 | functio ... ;\\n } | props.js:34:5:34:55 | new C({ ... ctor"}) |
|
||||
| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:2:16:2:15 | this |
|
||||
| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:3:9:3:12 | this |
|
||||
| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:5:9:5:12 | this |
|
||||
| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:7:9:7:12 | this |
|
||||
| statePropertyReads.js:1:1:13:1 | class R ... }\\n} | statePropertyReads.js:10:23:10:22 | this |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:2:16:2:15 | this |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:3:13:3:22 | cmp |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:3:19:3:22 | this |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:4:9:4:11 | cmp |
|
||||
@@ -21,28 +45,45 @@
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:14:9:14:11 | cmp |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:18:9:18:11 | cmp |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:22:9:22:11 | cmp |
|
||||
| statePropertyWrites.js:1:1:34:1 | class W ... };\\n} | statePropertyWrites.js:25:20:25:19 | this |
|
||||
| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} |
|
||||
| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:37:11:37:10 | this |
|
||||
| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:38:24:38:27 | this |
|
||||
| statePropertyWrites.js:36:19:45:1 | {\\n ren ... ;\\n }\\n} | statePropertyWrites.js:40:20:40:19 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:2:17:2:16 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:3:9:3:12 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:5:13:5:22 | dis |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:5:19:5:22 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:6:9:6:11 | dis |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:8:10:8:9 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:9:13:9:16 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:10:17:10:20 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:13:23:13:22 | this |
|
||||
| thisAccesses.js:1:1:16:1 | class C ... }\\n} | thisAccesses.js:14:9:14:12 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:19:13:19:12 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:20:10:20:9 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:21:13:21:16 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:22:17:22:20 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:26:25:26:24 | this |
|
||||
| thisAccesses.js:18:19:29:1 | {\\n r ... }\\n} | thisAccesses.js:27:9:27:12 | this |
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | thisAccesses.js:31:2:31:1 | this |
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | thisAccesses.js:32:6:32:5 | this |
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | thisAccesses.js:33:9:33:12 | this |
|
||||
| thisAccesses.js:31:2:36:1 | functio ... iv/>;\\n} | thisAccesses.js:34:13:34:16 | this |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | thisAccesses.js:39:13:39:12 | this |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | thisAccesses.js:40:38:40:37 | this |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | thisAccesses.js:41:13:41:16 | this |
|
||||
| thisAccesses.js:38:19:45:1 | {\\n r ... },\\n} | thisAccesses.js:42:12:42:15 | this |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:48:17:48:16 | this |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:49:9:49:12 | this |
|
||||
| thisAccesses.js:47:1:52:1 | class C ... }\\n} | thisAccesses.js:50:9:50:12 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:5:13:5:12 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:6:38:6:37 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:7:13:7:16 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:8:12:8:15 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:9:25:9:24 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:10:13:10:16 | this |
|
||||
| thisAccesses_importedMappers.js:4:19:15:1 | {\\n r ... },\\n} | thisAccesses_importedMappers.js:11:12:11:15 | this |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value |
|
||||
| jquery.js:4:5:4:11 | tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
|
||||
| jquery.js:7:5:7:34 | "<div i ... + "\\">" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
|
||||
| jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
this.addEventListener('message', function(event) {
|
||||
document.write(event.data); // NOT OK
|
||||
})
|
||||
@@ -1,8 +1,8 @@
|
||||
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | $@ flows directly to Http request body | bufferRead.js:33:21:33:28 | postData | File access |
|
||||
| googlecompiler.js:44:54:44:57 | data | $@ flows directly to Http request body | googlecompiler.js:38:18:38:26 | post_data | File access |
|
||||
| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | $@ flows directly to Http request body | readFileSync.js:26:18:26:18 | s | File access |
|
||||
| readStreamRead.js:13:21:13:35 | readable.read() | $@ flows directly to Http request body | readStreamRead.js:30:19:30:23 | chunk | File access |
|
||||
| request.js:28:52:28:55 | data | $@ flows directly to Http request body | request.js:8:11:8:20 | {jsonData} | File access |
|
||||
| request.js:43:51:43:54 | data | $@ flows directly to Http request body | request.js:16:11:23:3 | {\\n u ... ody\\n } | File access |
|
||||
| sentAsHeaders.js:10:79:10:84 | buffer | $@ flows directly to Http request body | sentAsHeaders.js:14:20:19:9 | {\\n ... } | File access |
|
||||
| sentAsHeaders.js:10:79:10:84 | buffer | $@ flows directly to Http request body | sentAsHeaders.js:20:20:25:9 | {\\n ... } | File access |
|
||||
| bufferRead.js:33:21:33:28 | postData | $@ flows directly to outbound network request | bufferRead.js:12:22:12:43 | new Buf ... s.size) | File data |
|
||||
| googlecompiler.js:38:18:38:26 | post_data | $@ flows directly to outbound network request | googlecompiler.js:44:54:44:57 | data | File data |
|
||||
| readFileSync.js:26:18:26:18 | s | $@ flows directly to outbound network request | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | File data |
|
||||
| readStreamRead.js:30:19:30:23 | chunk | $@ flows directly to outbound network request | readStreamRead.js:13:21:13:35 | readable.read() | File data |
|
||||
| request.js:8:11:8:20 | {jsonData} | $@ flows directly to outbound network request | request.js:28:52:28:55 | data | File data |
|
||||
| request.js:16:11:23:3 | {\\n u ... ody\\n } | $@ flows directly to outbound network request | request.js:43:51:43:54 | data | File data |
|
||||
| sentAsHeaders.js:14:20:19:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
|
||||
| sentAsHeaders.js:20:20:25:9 | {\\n ... } | $@ flows directly to outbound network request | sentAsHeaders.js:10:79:10:84 | buffer | File data |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
var express = require('express'),
|
||||
app = express();
|
||||
|
||||
app.get('/getFooFile', function(req, res) {
|
||||
res.sendFile("foo"); // OK (for now) since this is a server-side response
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
||||
// Automatically generated from TypeScript type definitions provided by
|
||||
// DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped),
|
||||
// which is licensed under the MIT license; see file DefinitelyTyped-LICENSE
|
||||
// in parent directory.
|
||||
// Type definitions for Node.js 10.5.x
|
||||
// Project: http://nodejs.org/
|
||||
// Definitions by: Microsoft TypeScript <http://typescriptlang.org>
|
||||
// DefinitelyTyped <https://github.com/DefinitelyTyped/DefinitelyTyped>
|
||||
// Parambir Singh <https://github.com/parambirs>
|
||||
// Christian Vaagland Tellnes <https://github.com/tellnes>
|
||||
// Wilco Bakker <https://github.com/WilcoBakker>
|
||||
// Nicolas Voigt <https://github.com/octo-sniffle>
|
||||
// Chigozirim C. <https://github.com/smac89>
|
||||
// Flarna <https://github.com/Flarna>
|
||||
// Mariusz Wiktorczyk <https://github.com/mwiktorczyk>
|
||||
// wwwy3y3 <https://github.com/wwwy3y3>
|
||||
// Deividas Bakanas <https://github.com/DeividasBakanas>
|
||||
// Kelvin Jin <https://github.com/kjin>
|
||||
// Alvis HT Tang <https://github.com/alvis>
|
||||
// Sebastian Silbermann <https://github.com/eps1lon>
|
||||
// Hannes Magnusson <https://github.com/Hannes-Magnusson-CK>
|
||||
// Alberto Schiabel <https://github.com/jkomyno>
|
||||
// Klaus Meinhardt <https://github.com/ajafff>
|
||||
// Huw <https://github.com/hoo29>
|
||||
// Nicolas Even <https://github.com/n-e>
|
||||
// Bruno Scheufler <https://github.com/brunoscheufler>
|
||||
// Mohsen Azimi <https://github.com/mohsen1>
|
||||
// Hoàng Văn Khải <https://github.com/KSXGitHub>
|
||||
// Alexander T. <https://github.com/a-tarasyuk>
|
||||
// Lishude <https://github.com/islishude>
|
||||
// Andrew Makarov <https://github.com/r3nya>
|
||||
// Zane Hannan AU <https://github.com/ZaneHannanAU>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/**
|
||||
* @externs
|
||||
* @fileoverview Definitions for module "fs"
|
||||
*/
|
||||
var fs = {};
|
||||
|
||||
/**
|
||||
* @param {number} fd
|
||||
* @param {Buffer} buffer
|
||||
* @param {number} offset
|
||||
* @param {number} length
|
||||
* @param {number} position
|
||||
* @param {(function(NodeJS.ErrnoException, number, Buffer): void)=} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.read = function(fd, buffer, offset, length, position, callback) {};
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {string} encoding
|
||||
* @param {(function(NodeJS.ErrnoException, string): void)} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.readFile = function(filename, encoding, callback) {};
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {{encoding: string, flag: string}} options
|
||||
* @param {(function(NodeJS.ErrnoException, string): void)} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.readFile = function(filename, options, callback) {};
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {{flag: string}} options
|
||||
* @param {(function(NodeJS.ErrnoException, Buffer): void)} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.readFile = function(filename, options, callback) {};
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {(function(NodeJS.ErrnoException, Buffer): void)} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.readFile = function(filename, callback) {};
|
||||
@@ -1,3 +1,3 @@
|
||||
| tst.js:16:33:16:33 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data received from Http response |
|
||||
| tst.js:19:25:19:25 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data received from Http response |
|
||||
| tst.js:24:22:24:22 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data received from Http response |
|
||||
| tst.js:16:33:16:33 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
| tst.js:19:25:19:25 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
| tst.js:24:22:24:22 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
// Automatically generated from TypeScript type definitions provided by
|
||||
// DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped),
|
||||
// which is licensed under the MIT license; see file DefinitelyTyped-LICENSE
|
||||
// in parent directory.
|
||||
// Type definitions for Node.js 10.5.x
|
||||
// Project: http://nodejs.org/
|
||||
// Definitions by: Microsoft TypeScript <http://typescriptlang.org>
|
||||
// DefinitelyTyped <https://github.com/DefinitelyTyped/DefinitelyTyped>
|
||||
// Parambir Singh <https://github.com/parambirs>
|
||||
// Christian Vaagland Tellnes <https://github.com/tellnes>
|
||||
// Wilco Bakker <https://github.com/WilcoBakker>
|
||||
// Nicolas Voigt <https://github.com/octo-sniffle>
|
||||
// Chigozirim C. <https://github.com/smac89>
|
||||
// Flarna <https://github.com/Flarna>
|
||||
// Mariusz Wiktorczyk <https://github.com/mwiktorczyk>
|
||||
// wwwy3y3 <https://github.com/wwwy3y3>
|
||||
// Deividas Bakanas <https://github.com/DeividasBakanas>
|
||||
// Kelvin Jin <https://github.com/kjin>
|
||||
// Alvis HT Tang <https://github.com/alvis>
|
||||
// Sebastian Silbermann <https://github.com/eps1lon>
|
||||
// Hannes Magnusson <https://github.com/Hannes-Magnusson-CK>
|
||||
// Alberto Schiabel <https://github.com/jkomyno>
|
||||
// Klaus Meinhardt <https://github.com/ajafff>
|
||||
// Huw <https://github.com/hoo29>
|
||||
// Nicolas Even <https://github.com/n-e>
|
||||
// Bruno Scheufler <https://github.com/brunoscheufler>
|
||||
// Mohsen Azimi <https://github.com/mohsen1>
|
||||
// Hoàng Văn Khải <https://github.com/KSXGitHub>
|
||||
// Alexander T. <https://github.com/a-tarasyuk>
|
||||
// Lishude <https://github.com/islishude>
|
||||
// Andrew Makarov <https://github.com/r3nya>
|
||||
// Zane Hannan AU <https://github.com/ZaneHannanAU>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
/**
|
||||
* @externs
|
||||
* @fileoverview Definitions for module "fs"
|
||||
*/
|
||||
var fs = {};
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {*} data
|
||||
* @param {(function(NodeJS.ErrnoException): void)=} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.writeFile = function(filename, data, callback) {};
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {*} data
|
||||
* @param {{encoding: string, mode: number, flag: string}} options
|
||||
* @param {(function(NodeJS.ErrnoException): void)=} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.writeFile = function(filename, data, options, callback) {};
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {*} data
|
||||
* @param {{encoding: string, mode: string, flag: string}} options
|
||||
* @param {(function(NodeJS.ErrnoException): void)=} callback
|
||||
* @return {void}
|
||||
*/
|
||||
fs.writeFile = function(filename, data, options, callback) {};
|
||||
Reference in New Issue
Block a user