Merge branch 'main' into moreReDoS

This commit is contained in:
Erik Krogh Kristensen
2020-11-17 17:34:49 +01:00
357 changed files with 9192 additions and 5175 deletions

View File

@@ -0,0 +1,22 @@
/**
* Provides shared predicates related to contextual queries in the code viewer.
*/
import semmle.files.FileSystem
/**
* Returns the `File` matching the given source file name as encoded by the VS
* Code extension.
*/
cached
File getFileBySourceArchiveName(string name) {
// The name provided for a file in the source archive by the VS Code extension
// has some differences from the absolute path in the database:
// 1. colons are replaced by underscores
// 2. there's a leading slash, even for Windows paths: "C:/foo/bar" ->
// "/C_/foo/bar"
// 3. double slashes in UNC prefixes are replaced with a single slash
// We can handle 2 and 3 together by unconditionally adding a leading slash
// before replacing double slashes.
name = ("/" + result.getAbsolutePath().replaceAll(":", "_")).replaceAll("//", "/")
}

View File

@@ -4,6 +4,7 @@
*/
import javascript
import IDEContextual
private import Declarations.Declarations
/**
@@ -178,11 +179,3 @@ ASTNode definitionOf(Locatable e, string kind) {
or
jsdocTypeLookup(e, result, kind)
}
/**
* Returns an appropriately encoded version of a filename `name`
* passed by the VS Code extension in order to coincide with the
* output of `.getFile()` on locatable entities.
*/
cached
File getEncodedFile(string name) { result.getAbsolutePath().replaceAll(":", "_") = name }

View File

@@ -123,9 +123,11 @@ module Cookie {
class InsecureJsCookie extends Cookie {
InsecureJsCookie() {
this =
[DataFlow::globalVarRef("Cookie"),
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
DataFlow::moduleImport("js-cookie")].getAMemberCall("set")
[
DataFlow::globalVarRef("Cookie"),
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
DataFlow::moduleImport("js-cookie")
].getAMemberCall("set")
}
override string getKind() { result = "js-cookie" }

View File

@@ -79,12 +79,14 @@ import semmle.javascript.frameworks.ClosureLibrary
import semmle.javascript.frameworks.CookieLibraries
import semmle.javascript.frameworks.Credentials
import semmle.javascript.frameworks.CryptoLibraries
import semmle.javascript.frameworks.DateFunctions
import semmle.javascript.frameworks.DigitalOcean
import semmle.javascript.frameworks.Electron
import semmle.javascript.frameworks.EventEmitter
import semmle.javascript.frameworks.Files
import semmle.javascript.frameworks.Firebase
import semmle.javascript.frameworks.jQuery
import semmle.javascript.frameworks.JWT
import semmle.javascript.frameworks.Handlebars
import semmle.javascript.frameworks.LazyCache
import semmle.javascript.frameworks.LodashUnderscore

View File

@@ -12,5 +12,5 @@ import definitions
external string selectedSourceFile();
from Locatable e, ASTNode def, string kind
where def = definitionOf(e, kind) and e.getFile() = getEncodedFile(selectedSourceFile())
where def = definitionOf(e, kind) and e.getFile() = getFileBySourceArchiveName(selectedSourceFile())
select e, def, kind

View File

@@ -12,5 +12,6 @@ import definitions
external string selectedSourceFile();
from Locatable e, ASTNode def, string kind
where def = definitionOf(e, kind) and def.getFile() = getEncodedFile(selectedSourceFile())
where
def = definitionOf(e, kind) and def.getFile() = getFileBySourceArchiveName(selectedSourceFile())
select e, def, kind

View File

@@ -23,6 +23,6 @@ class PrintAstConfigurationOverride extends PrintAstConfiguration {
*/
override predicate shouldPrint(Locatable e, Location l) {
super.shouldPrint(e, l) and
l.getFile() = getEncodedFile(selectedSourceFile())
l.getFile() = getFileBySourceArchiveName(selectedSourceFile())
}
}

View File

@@ -40,6 +40,40 @@ class ES2015Module extends Module {
}
}
/**
* Holds if `mod` contains one or more named export declarations other than `default`.
*/
private predicate hasNamedExports(ES2015Module mod) {
mod.getAnExport().(ExportNamedDeclaration).getASpecifier().getExportedName() != "default"
or
exists(mod.getAnExport().(ExportNamedDeclaration).getAnExportedDecl())
or
// Bulk re-exports only export named bindings (not "default")
mod.getAnExport() instanceof BulkReExportDeclaration
}
/**
* Holds if this module contains a `default` export.
*/
private predicate hasDefaultExport(ES2015Module mod) {
// export default foo;
mod.getAnExport() instanceof ExportDefaultDeclaration
or
// export { foo as default };
mod.getAnExport().(ExportNamedDeclaration).getASpecifier().getExportedName() = "default"
}
/**
* Holds if `mod` contains both named and `default` exports.
*
* This is used to determine whether a default-import of the module should be reinterpreted
* as a namespace-import, to accomodate the non-standard behavior implemented by some compilers.
*/
private predicate hasBothNamedAndDefaultExports(ES2015Module mod) {
hasNamedExports(mod) and
hasDefaultExport(mod)
}
/**
* An import declaration.
*
@@ -70,6 +104,10 @@ class ImportDeclaration extends Stmt, Import, @import_declaration {
is instanceof ImportNamespaceSpecifier and
count(getASpecifier()) = 1
or
// For compatibility with the non-standard implementation of default imports,
// treat default imports as namespace imports in cases where it can't cause ambiguity
// between named exports and the properties of a default-exported object.
not hasBothNamedAndDefaultExports(getImportedModule()) and
is.getImportedName() = "default"
)
or

View File

@@ -13,9 +13,11 @@ class JsonStringifyCall extends DataFlow::CallNode {
callee = DataFlow::globalVarRef("JSON").getAPropertyRead("stringify") or
callee = DataFlow::moduleMember("json3", "stringify") or
callee =
DataFlow::moduleImport(["json-stringify-safe", "json-stable-stringify", "stringify-object",
"fast-json-stable-stringify", "fast-safe-stringify", "javascript-stringify",
"js-stringify"]) or
DataFlow::moduleImport([
"json-stringify-safe", "json-stable-stringify", "stringify-object",
"fast-json-stable-stringify", "fast-safe-stringify", "javascript-stringify",
"js-stringify"
]) or
// require("util").inspect() and similar
callee = DataFlow::moduleMember("util", "inspect") or
callee = DataFlow::moduleImport(["pretty-format", "object-inspect"])

View File

@@ -205,15 +205,18 @@ private predicate isRequire(DataFlow::Node nd) {
or
isRequire(nd.getAPredecessor())
or
// `import { createRequire } from 'module';` support.
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate.
exists(ImportDeclaration imp | imp.getImportedPath().getValue() = "module" |
nd =
imp
.getImportedModuleNode()
.(DataFlow::SourceNode)
.getAPropertyRead("createRequire")
.getACall()
// `import { createRequire } from 'module';`.
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate and to avoid
// negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`.
exists(ImportDeclaration imp, DataFlow::SourceNode baseObj |
imp.getImportedPath().getValue() = "module"
|
baseObj =
[
DataFlow::destructuredModuleImportNode(imp),
DataFlow::valueNode(imp.getASpecifier().(ImportNamespaceSpecifier))
] and
nd = baseObj.getAPropertyRead("createRequire").getACall()
)
}

View File

@@ -299,8 +299,10 @@ module PromiseFlow {
or
prop = errorProp() and
value =
[promise.getRejectParameter().getACall().getArgument(0),
promise.getExecutor().getExceptionalReturn()]
[
promise.getRejectParameter().getACall().getArgument(0),
promise.getExecutor().getExceptionalReturn()
]
)
or
// promise creation call, e.g. `Promise.resolve`.

View File

@@ -699,8 +699,10 @@ module TaintTracking {
private DataFlow::PropRead getAStaticCaptureRef() {
result =
DataFlow::globalVarRef("RegExp")
.getAPropertyRead(["$" + [1 .. 9], "input", "lastMatch", "leftContext", "rightContext",
"$&", "$^", "$`"])
.getAPropertyRead([
"$" + [1 .. 9], "input", "lastMatch", "leftContext", "rightContext", "$&", "$^",
"$`"
])
}
/**

View File

@@ -318,7 +318,12 @@ private class AnalyzedVariableExport extends AnalyzedPropertyWrite, DataFlow::Va
override predicate writes(AbstractValue baseVal, string propName, DataFlow::AnalyzedNode source) {
baseVal = TAbstractExportsObject(export.getEnclosingModule()) and
propName = name and
source = varDef.getSource().analyze()
(
source = varDef.getSource().analyze()
or
varDef.getTarget() instanceof DestructuringPattern and
source = export.getSourceNode(propName)
)
}
override predicate writesValue(AbstractValue baseVal, string propName, AbstractValue val) {

View File

@@ -0,0 +1,93 @@
/** Provides taint steps modeling flow through date-manipulation libraries. */
private import javascript
private module DateFns {
private API::Node formatFunction() {
result = API::moduleImport(["date-fns", "date-fns/esm"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport([
"date-fns/format", "date-fns/lightFormat", "date-fns/esm/format",
"date-fns/esm/lightFormat"
])
}
private API::Node curriedFormatFunction() {
result =
API::moduleImport(["date-fns/fp", "date-fns/esm/fp"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport([
"date-fns/fp/format", "date-fns/fp/lightFormat", "date-fns/esm/fp/format",
"date-fns/esm/fp/lightFormat"
])
}
/**
* Taint step of form: `f -> format(date, f)`
*
* A format string can use single-quotes to include mostly arbitrary text.
*/
private class FormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
FormatStep() { this = formatFunction().getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(1) and
succ = this
}
}
/**
* Taint step of form: `f -> format(f)(date)`
*/
private class CurriedFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
CurriedFormatStep() { this = curriedFormatFunction().getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = getACall()
}
}
}
private module Moment {
/** Gets a reference to a `moment` object. */
private API::Node moment() {
result = API::moduleImport(["moment", "moment-timezone"])
or
result = moment().getReturn()
or
result = moment().getAMember()
}
/**
* Taint step of form: `f -> momentObj.format(f)`
*
* The format string can use backslash-escaping to include mostly arbitrary text.
*/
private class MomentFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
MomentFormatStep() { this = moment().getMember("format").getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = this
}
}
}
private module DateFormat {
/**
* Taint step of form: `x -> dateformat(..., x)`
*
* The format string can use single-quotes to include mostly arbitrary text.
*/
private class DateFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
DateFormatStep() { this = DataFlow::moduleImport("dateformat").getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(1) and
succ = this
}
}
}

View File

@@ -491,8 +491,10 @@ module Express {
RequestInputAccess() {
kind = "parameter" and
this =
[getAQueryObjectReference(DataFlow::TypeTracker::end(), rh),
getAParamsObjectReference(DataFlow::TypeTracker::end(), rh)].getAPropertyRead()
[
getAQueryObjectReference(DataFlow::TypeTracker::end(), rh),
getAParamsObjectReference(DataFlow::TypeTracker::end(), rh)
].getAPropertyRead()
or
exists(DataFlow::SourceNode request | request = rh.getARequestSource().ref() |
kind = "parameter" and

View File

@@ -118,8 +118,10 @@ module Fastify {
.flow()
.(DataFlow::MethodCallNode)
.getOptionArgument(0,
["onRequest", "preParsing", "preValidation", "preHandler", "preSerialization",
"onSend", "onResponse", "handler"])
[
"onRequest", "preParsing", "preValidation", "preHandler", "preSerialization",
"onSend", "onResponse", "handler"
])
else result = getLastArgument().flow()
}
}

View File

@@ -0,0 +1,50 @@
/**
* Provides classes for working with JWT libraries.
*/
import javascript
/**
* Provides classes and predicates modeling the `jwt-decode` libary.
*/
private module JwtDecode {
/**
* A taint-step for `succ = require("jwt-decode")(pred)`.
*/
private class JwtDecodeStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
JwtDecodeStep() { this = DataFlow::moduleImport("jwt-decode").getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = this.getArgument(0) and
succ = this
}
}
}
/**
* Provides classes and predicates modeling the `jsonwebtoken` libary.
*/
private module JsonWebToken {
/**
* A taint-step for `require("jsonwebtoken").verify(pred, "key", (err succ) => {...})`.
*/
private class VerifyStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
VerifyStep() { this = DataFlow::moduleMember("jsonwebtoken", "verify").getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = this.getArgument(0) and
succ = this.getABoundCallbackParameter(2, 1)
}
}
/**
* The private key for a JWT as a `CredentialsExpr`.
*/
private class JWTKey extends CredentialsExpr {
JWTKey() {
this = DataFlow::moduleMember("jsonwebtoken", "sign").getACall().getArgument(1).asExpr()
}
override string getCredentialsKind() { result = "key" }
}
}

View File

@@ -403,16 +403,18 @@ module LodashUnderscore {
call = any(Member member | member.getName() = name).getACall()
|
name =
["find", "filter", "findWhere", "where", "reject", "pluck", "max", "min", "sortBy",
"shuffle", "sample", "toArray", "partition", "compact", "first", "initial", "last",
"rest", "flatten", "without", "difference", "uniq", "unique", "unzip", "transpose",
"object", "chunk", "values", "mapObject", "pick", "omit", "defaults", "clone", "tap",
"identity",
// String category
"camelCase", "capitalize", "deburr", "kebabCase", "lowerCase", "lowerFirst", "pad",
"padEnd", "padStart", "repeat", "replace", "snakeCase", "split", "startCase", "toLower",
"toUpper", "trim", "trimEnd", "trimStart", "truncate", "unescape", "upperCase",
"upperFirst", "words"] and
[
"find", "filter", "findWhere", "where", "reject", "pluck", "max", "min", "sortBy",
"shuffle", "sample", "toArray", "partition", "compact", "first", "initial", "last",
"rest", "flatten", "without", "difference", "uniq", "unique", "unzip", "transpose",
"object", "chunk", "values", "mapObject", "pick", "omit", "defaults", "clone", "tap",
"identity",
// String category
"camelCase", "capitalize", "deburr", "kebabCase", "lowerCase", "lowerFirst", "pad",
"padEnd", "padStart", "repeat", "replace", "snakeCase", "split", "startCase", "toLower",
"toUpper", "trim", "trimEnd", "trimStart", "truncate", "unescape", "upperCase",
"upperFirst", "words"
] and
pred = call.getArgument(0) and
succ = call
or

View File

@@ -798,10 +798,12 @@ private module Redis {
bindingset[argIndex]
predicate argumentIsAmbiguousKey(string method, int argIndex) {
method =
["set", "publish", "append", "bitfield", "decrby", "getset", "hincrby", "hincrbyfloat",
"hset", "hsetnx", "incrby", "incrbyfloat", "linsert", "lpush", "lpushx", "lset",
"ltrim", "rename", "renamenx", "rpushx", "setbit", "setex", "smove", "zincrby",
"zinterstore", "hdel", "lpush", "pfadd", "rpush", "sadd", "sdiffstore", "srem"] and
[
"set", "publish", "append", "bitfield", "decrby", "getset", "hincrby", "hincrbyfloat",
"hset", "hsetnx", "incrby", "incrbyfloat", "linsert", "lpush", "lpushx", "lset", "ltrim",
"rename", "renamenx", "rpushx", "setbit", "setex", "smove", "zincrby", "zinterstore",
"hdel", "lpush", "pfadd", "rpush", "sadd", "sdiffstore", "srem"
] and
argIndex = 0
or
method = ["bitop", "hmset", "mset", "msetnx", "geoadd"] and argIndex >= 0

View File

@@ -472,8 +472,10 @@ module NodeJSLib {
result = promisifyAllCall and
pred.flowsTo(promisifyAllCall.getArgument(0)) and
promisifyAllCall =
[DataFlow::moduleMember("bluebird", "promisifyAll"),
DataFlow::moduleImport("util-promisifyall")].getACall()
[
DataFlow::moduleMember("bluebird", "promisifyAll"),
DataFlow::moduleImport("util-promisifyall")
].getACall()
)
)
}
@@ -771,8 +773,10 @@ module NodeJSLib {
* Gets the code to be executed as part of this invocation.
*/
DataFlow::Node getACodeArgument() {
memberName in ["Script", "SourceTextModule", "compileFunction", "runInContext",
"runInNewContext", "runInThisContext"] and
memberName in [
"Script", "SourceTextModule", "compileFunction", "runInContext", "runInNewContext",
"runInThisContext"
] and
// all of the above methods/constructors take the command as their first argument
result = getArgument(0)
}

View File

@@ -569,10 +569,12 @@ private class UseStateStep extends PreCallGraphStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::CallNode call | call = react().getAMemberCall("useState") |
pred =
[call.getArgument(0), // initial state
call.getCallback(0).getReturnNode(), // lazy initial state
call.getAPropertyRead("1").getACall().getArgument(0), // setState invocation
call.getAPropertyRead("1").getACall().getCallback(0).getReturnNode()] and // setState with callback
[
call.getArgument(0), // initial state
call.getCallback(0).getReturnNode(), // lazy initial state
call.getAPropertyRead("1").getACall().getArgument(0), // setState invocation
call.getAPropertyRead("1").getACall().getCallback(0).getReturnNode() // setState with callback
] and
succ = call.getAPropertyRead("0")
or
// Propagate current state into the callback argument of `setState(prevState => { ... })`

View File

@@ -33,8 +33,10 @@ module Vue {
/** Gets the name of a lifecycle hook method. */
private string lifecycleHookName() {
result =
["beforeCreate", "created", "beforeMount", "mounted", "beforeUpdate", "updated", "activated",
"deactivated", "beforeDestroy", "destroyed", "errorCaptured"]
[
"beforeCreate", "created", "beforeMount", "mounted", "beforeUpdate", "updated", "activated",
"deactivated", "beforeDestroy", "destroyed", "errorCaptured"
]
}
/** Gets a value that can be used as a `@Component` decorator. */

View File

@@ -53,8 +53,10 @@ module ImproperCodeSanitization {
|
functionLeaf
.getStringValue()
.regexpMatch([".*function( )?([a-zA-Z0-9]+)?( )?\\(.*", ".*eval\\(.*",
".*new Function\\(.*", "(^|.*[^a-zA-Z0-9])\\(.*\\)( )?=>.*"])
.regexpMatch([
".*function( )?([a-zA-Z0-9]+)?( )?\\(.*", ".*eval\\(.*", ".*new Function\\(.*",
"(^|.*[^a-zA-Z0-9])\\(.*\\)( )?=>.*"
])
)
)
}

View File

@@ -66,9 +66,11 @@ module IndirectCommandInjection {
exists(string method |
not method =
// the methods that does not return a chained `yargs` object.
["getContext", "getDemandedOptions", "getDemandedCommands", "getDeprecatedOptions",
"_getParseContext", "getOptions", "getGroups", "getStrict", "getStrictCommands",
"getExitProcess", "locale", "getUsageInstance", "getCommandInstance"]
[
"getContext", "getDemandedOptions", "getDemandedCommands", "getDeprecatedOptions",
"_getParseContext", "getOptions", "getGroups", "getStrict", "getStrictCommands",
"getExitProcess", "locale", "getUsageInstance", "getCommandInstance"
]
|
result = yargs().getAMethodCall(method)
)

View File

@@ -96,8 +96,10 @@ module InsecureDownload {
*/
string unsafeExtension() {
result =
["exe", "dmg", "pkg", "tar.gz", "zip", "sh", "bat", "cmd", "app", "apk", "msi", "dmg",
"tar.gz", "zip", "js", "py", "jar", "war"]
[
"exe", "dmg", "pkg", "tar.gz", "zip", "sh", "bat", "cmd", "app", "apk", "msi", "dmg",
"tar.gz", "zip", "js", "py", "jar", "war"
]
}
/**

View File

@@ -105,8 +105,10 @@ module UnsafeShellCommandConstruction {
ArrayAppendEndingInCommandExecutinSink() {
this =
[array.(DataFlow::ArrayCreationNode).getAnElement(),
array.getAMethodCall(["push", "unshift"]).getAnArgument()] and
[
array.(DataFlow::ArrayCreationNode).getAnElement(),
array.getAMethodCall(["push", "unshift"]).getAnArgument()
] and
exists(DataFlow::MethodCallNode joinCall | array.getAMethodCall("join") = joinCall |
joinCall = isExecutedAsShellCommand(DataFlow::TypeBackTracker::end(), sys) and
joinCall.getNumArgument() = 1 and

View File

@@ -0,0 +1,7 @@
let source = 'tainted';
export const x = source;
export default {
x: 'safe'
};

View File

@@ -0,0 +1,7 @@
import defaultValue from './mixedExports';
import { x } from './mixedExports';
import * as ns from './mixedExports';
let sink1 = defaultValue.x; // OK
let sink2 = x; // NOT OK
let sink3 = ns.x; // NOT OK

View File

@@ -26,6 +26,8 @@ dataFlow
| global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) |
| global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) |
| global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:6:13:6:13 | x |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:7:13:7:16 | ns.x |
| nodeJsLib.js:2:15:2:23 | "tainted" | esClient.js:7:13:7:18 | nj.foo |
| nodeJsLib.js:2:15:2:23 | "tainted" | esClient.js:10:13:10:17 | njFoo |
| nodeJsLib.js:2:15:2:23 | "tainted" | nodeJsClient.js:4:13:4:18 | nj.foo |
@@ -106,6 +108,8 @@ taintTracking
| global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) |
| global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) |
| global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:6:13:6:13 | x |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:7:13:7:16 | ns.x |
| nodeJsLib.js:1:15:1:23 | "tainted" | esClient.js:7:13:7:18 | nj.foo |
| nodeJsLib.js:1:15:1:23 | "tainted" | esClient.js:10:13:10:17 | njFoo |
| nodeJsLib.js:1:15:1:23 | "tainted" | nodeJsClient.js:4:13:4:18 | nj.foo |
@@ -209,6 +213,8 @@ germanFlow
| global.js:2:15:2:24 | "tainted2" | global.js:10:13:10:22 | g(source2) |
| global.js:5:22:5:35 | "also tainted" | global.js:9:13:9:22 | g(source1) |
| global.js:5:22:5:35 | "also tainted" | global.js:10:13:10:22 | g(source2) |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:6:13:6:13 | x |
| mixedExports.js:1:14:1:22 | 'tainted' | mixedExportsClient.js:7:13:7:16 | ns.x |
| nodeJsLib.js:2:15:2:23 | "tainted" | esClient.js:7:13:7:18 | nj.foo |
| nodeJsLib.js:2:15:2:23 | "tainted" | esClient.js:10:13:10:17 | njFoo |
| nodeJsLib.js:2:15:2:23 | "tainted" | nodeJsClient.js:4:13:4:18 | nj.foo |

View File

@@ -717,19 +717,13 @@
| (parameter 0 (member log (member console (global)))) | src/m3/index.js:3:43:3:61 | m1("Hello, world!") | true |
| (parameter 0 (member m (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:15:4:18 | "hi" | false |
| (parameter 0 (member m (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:15:4:18 | "hi" | true |
| (parameter 0 (member m (instance (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:15:4:18 | "hi" | false |
| (parameter 0 (member m (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:2:5:2:8 | "hi" | false |
| (parameter 0 (member m (return (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:15:4:18 | "hi" | false |
| (parameter 0 (member m (return (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:15:4:18 | "hi" | false |
| (parameter 0 (member m (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:2:5:2:8 | "hi" | false |
| (parameter 0 (member readFileSync (root https://www.npmjs.com/package/fs))) | src/m5/index.js:5:49:5:49 | f | false |
| (parameter 0 (member s (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:15:5:21 | "there" | false |
| (parameter 0 (member s (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:15:5:21 | "there" | true |
| (parameter 0 (member s (instance (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:15:5:21 | "there" | false |
| (parameter 0 (member s (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:3:5:3:11 | "there" | false |
| (parameter 0 (member s (return (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:15:5:21 | "there" | false |
| (parameter 0 (member s (return (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:15:5:21 | "there" | false |
| (parameter 0 (member s (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:3:5:3:11 | "there" | false |
| (parameter 0 (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:6:2:8 | foo | true |
| (parameter 0 (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic))))))))) | src/cyclic/index.js:2:6:2:8 | foo | true |
| (parameter 0 (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (return (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:6:2:8 | foo | true |
@@ -1020,8 +1014,6 @@
| (parameter 0 (parameter 0 (return (return (return (return (return (return (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:6:2:8 | foo | true |
| (parameter 0 (parameter 1 (member then (instance (member Promise (root https://www.npmjs.com/package/bluebird)))))) | src/bluebird/index.js:6:12:6:15 | null | true |
| (parameter 0 (root https://www.npmjs.com/package/m1)) | src/m3/index.js:3:46:3:60 | "Hello, world!" | false |
| (parameter 0 (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:4:7:4:10 | "me" | false |
| (parameter 0 (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:5:7:5:10 | "me" | false |
| (return (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:3:10:3:12 | foo | true |
| (return (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic))))))))) | src/cyclic/index.js:3:10:3:12 | foo | true |
| (return (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (return (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:3:10:3:12 | foo | true |

View File

@@ -20,8 +20,6 @@
| (instance (member default (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:4:1:4:11 | new A("me") | true |
| (instance (member default (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:5:1:5:11 | new A("me") | false |
| (instance (member default (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:5:1:5:11 | new A("me") | true |
| (instance (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:4:1:4:11 | new A("me") | false |
| (instance (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:5:1:5:11 | new A("me") | false |
| (member String (global)) | src/m5/index.js:5:26:5:31 | String | true |
| (member console (global)) | src/m2/main.js:2:3:2:9 | console | true |
| (member console (global)) | src/m2/main.js:12:5:12:11 | console | true |
@@ -34,20 +32,14 @@
| (member log (member console (global))) | src/m3/index.js:3:31:3:41 | console.log | true |
| (member m (instance (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:1:4:13 | new A("me").m | false |
| (member m (instance (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:1:4:13 | new A("me").m | true |
| (member m (instance (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:4:1:4:13 | new A("me").m | false |
| (member m (member default (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:2:1:2:3 | A.m | false |
| (member m (return (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:1:4:13 | new A("me").m | false |
| (member m (return (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:4:1:4:13 | new A("me").m | false |
| (member m (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:2:1:2:3 | A.m | false |
| (member name (instance (member default (root https://www.npmjs.com/package/m2)))) | src/m2/main.js:12:27:12:35 | this.name | true |
| (member readFileSync (root https://www.npmjs.com/package/fs)) | src/m5/index.js:5:33:5:47 | fs.readFileSync | false |
| (member s (instance (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:1:5:13 | new A("me").s | false |
| (member s (instance (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:1:5:13 | new A("me").s | true |
| (member s (instance (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:5:1:5:13 | new A("me").s | false |
| (member s (member default (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:3:1:3:3 | A.s | false |
| (member s (return (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:1:5:13 | new A("me").s | false |
| (member s (return (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:5:1:5:13 | new A("me").s | false |
| (member s (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:3:1:3:3 | A.s | false |
| (member x (parameter 0 (member foo (root https://www.npmjs.com/package/m2)))) | src/m2/main.js:2:15:2:17 | p.x | true |
| (member y (member x (parameter 0 (member foo (root https://www.npmjs.com/package/m2))))) | src/m2/main.js:2:15:2:19 | p.x.y | true |
| (parameter 0 (member Promise (root https://www.npmjs.com/package/bluebird))) | src/bluebird/index.js:1:18:1:21 | exec | true |
@@ -764,19 +756,13 @@
| (return (member log (member console (global)))) | src/m3/index.js:3:31:3:62 | console ... rld!")) | true |
| (return (member m (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:1:4:19 | new A("me").m("hi") | false |
| (return (member m (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:1:4:19 | new A("me").m("hi") | true |
| (return (member m (instance (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:1:4:19 | new A("me").m("hi") | false |
| (return (member m (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:2:1:2:9 | A.m("hi") | false |
| (return (member m (return (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:4:1:4:19 | new A("me").m("hi") | false |
| (return (member m (return (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:4:1:4:19 | new A("me").m("hi") | false |
| (return (member m (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:2:1:2:9 | A.m("hi") | false |
| (return (member readFileSync (root https://www.npmjs.com/package/fs))) | src/m5/index.js:5:33:5:50 | fs.readFileSync(f) | false |
| (return (member s (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:1:5:22 | new A(" ... there") | false |
| (return (member s (instance (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:1:5:22 | new A(" ... there") | true |
| (return (member s (instance (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:1:5:22 | new A(" ... there") | false |
| (return (member s (member default (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:3:1:3:12 | A.s("there") | false |
| (return (member s (return (member default (root https://www.npmjs.com/package/m2))))) | src/m3/tst3.js:5:1:5:22 | new A(" ... there") | false |
| (return (member s (return (root https://www.npmjs.com/package/m2)))) | src/m3/tst3.js:5:1:5:22 | new A(" ... there") | false |
| (return (member s (root https://www.npmjs.com/package/m2))) | src/m3/tst3.js:3:1:3:12 | A.s("there") | false |
| (return (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:3:2:9 | cb(foo) | true |
| (return (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (member foo (root https://www.npmjs.com/package/cyclic))))))))) | src/cyclic/index.js:2:3:2:9 | cb(foo) | true |
| (return (parameter 0 (member f00 (member f00 (member f00 (member f00 (member f00 (return (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:3:2:9 | cb(foo) | true |
@@ -1067,11 +1053,8 @@
| (return (parameter 0 (return (return (return (return (return (return (member foo (root https://www.npmjs.com/package/cyclic)))))))))) | src/cyclic/index.js:2:3:2:9 | cb(foo) | true |
| (return (parameter 1 (member then (instance (member Promise (root https://www.npmjs.com/package/bluebird)))))) | src/bluebird/index.js:6:3:6:16 | rejected(null) | true |
| (return (root https://www.npmjs.com/package/m1)) | src/m3/index.js:3:43:3:61 | m1("Hello, world!") | false |
| (return (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:4:1:4:11 | new A("me") | false |
| (return (root https://www.npmjs.com/package/m2)) | src/m3/tst3.js:5:1:5:11 | new A("me") | false |
| (root https://www.npmjs.com/package/base-64/base64.js) | src/m5/index.js:2:14:2:41 | require ... 64.js") | false |
| (root https://www.npmjs.com/package/fs) | src/m5/index.js:1:12:1:24 | require("fs") | false |
| (root https://www.npmjs.com/package/m1) | src/m3/index.js:1:10:1:22 | require("m1") | false |
| (root https://www.npmjs.com/package/m2) | src/m3/tst2.js:1:1:1:25 | import ... m "m2"; | false |
| (root https://www.npmjs.com/package/m2) | src/m3/tst3.js:1:1:1:19 | import A from "m2"; | false |
| (root https://www.npmjs.com/package/m2) | src/m3/tst3.js:1:8:1:8 | A | false |

View File

@@ -0,0 +1,10 @@
range
| tst.js:1:13:1:17 | [w-z] | tst.js:1:14:1:16 | w-z |
| tst.js:6:13:6:19 | [\\n-\\r] | tst.js:6:14:6:18 | \\n-\\r |
| tst.js:7:13:7:18 | [\\n-z] | tst.js:7:14:7:17 | \\n-z |
escapeClass
| tst.js:2:13:2:16 | [\\w] | tst.js:2:14:2:15 | \\w |
| tst.js:3:13:3:18 | [\\w-z] | tst.js:3:14:3:15 | \\w |
| tst.js:4:13:4:19 | [\\w-\\w] | tst.js:4:14:4:15 | \\w |
| tst.js:4:13:4:19 | [\\w-\\w] | tst.js:4:17:4:18 | \\w |
| tst.js:5:13:5:18 | [z-\\w] | tst.js:5:16:5:17 | \\w |

View File

@@ -0,0 +1,9 @@
import javascript
query predicate range(RegExpCharacterClass cla, RegExpCharacterRange range) {
cla.getAChild() = range
}
query predicate escapeClass(RegExpCharacterClass cla, RegExpCharacterClassEscape escape) {
cla.getAChild() = escape
}

View File

@@ -0,0 +1,7 @@
var reg1 = /[w-z]/; // normal range w-z, matches: wxyz
var reg2 = /[\w]/; // escape class, same as \w.
var reg3 = /[\w-z]/; // escape class \w and "-" and "z", same as [a-zA-Z0-9\-z]
var reg4 = /[\w-\w]/; // escape class \w (twice) and the char "-".
var reg5 = /[z-\w]/; // same as reg3
var reg6 = /[\n-\r]/; // from \n (code 10) to \r (code 13).
var reg7 = /[\n-z]/; // from \n (code 10) to z (code 122).

View File

@@ -0,0 +1,4 @@
import { foo, bar } from './destructuring-export';
foo(); // track: destructuring-export-foo
bar(); // track: destructuring-export-bar

View File

@@ -0,0 +1,4 @@
export const {
foo, // name: destructuring-export-foo
bar, // name: destructuring-export-bar
} = new Something();

View File

@@ -81,9 +81,11 @@
| regexplib/address.js:95:379:95:755 | [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\' ]+ | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\']+' |
| regexplib/email.js:8:16:8:49 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | it can start matching anywhere |
| regexplib/email.js:12:2:12:4 | \\w+ | it can start matching anywhere |
| regexplib/email.js:15:6:15:13 | [\\w-\\.]* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/email.js:15:28:15:30 | \\w* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/email.js:20:3:20:6 | \\w+? | it can start matching anywhere |
| regexplib/email.js:28:2:28:4 | \\w+ | it can start matching anywhere |
| regexplib/email.js:28:5:28:12 | [\\w-\\.]* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/email.js:28:27:28:29 | \\w* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/email.js:28:73:28:87 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere |
| regexplib/email.js:28:125:28:139 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere |
@@ -173,9 +175,11 @@
| regexplib/uri.js:34:3:34:9 | [^\\=&]+ | it can start matching anywhere |
| regexplib/uri.js:39:7:39:9 | .*? | it can start matching anywhere after the start of the preceeding '<a' |
| regexplib/uri.js:44:2:44:4 | .*? | it can start matching anywhere |
| regexplib/uri.js:47:31:47:36 | [\\w-]+ | it can start matching anywhere after the start of the preceeding '[\\w-\\s]*' |
| regexplib/uri.js:53:3:53:9 | [^\\=&]+ | it can start matching anywhere |
| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | it can start matching anywhere |
| regexplib/uri.js:59:2:59:13 | [a-zA-Z]{3,} | it can start matching anywhere |
| regexplib/uri.js:64:31:64:36 | [\\w-]+ | it can start matching anywhere after the start of the preceeding '[\\w-\\s]*' |
| regexplib/uri.js:73:2:73:4 | .*? | it can start matching anywhere |
| tst.js:14:13:14:18 | (.*,)+ | it can start matching anywhere |
| tst.js:14:14:14:15 | .* | it can start matching anywhere |

View File

@@ -89,6 +89,32 @@ nodes
| classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name |
| classnames.js:15:52:15:62 | window.name |
| dates.js:9:9:9:69 | taint |
| dates.js:9:17:9:69 | decodeU ... ing(1)) |
| dates.js:9:36:9:50 | window.location |
| dates.js:9:36:9:50 | window.location |
| dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:68 | window. ... ring(1) |
| dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:42:11:68 | dateFns ... taint) |
| dates.js:11:63:11:67 | taint |
| dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:42:12:71 | dateFns ... taint) |
| dates.js:12:66:12:70 | taint |
| dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:42:13:70 | dateFns ... )(time) |
| dates.js:13:59:13:63 | taint |
| dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:42:16:67 | moment( ... (taint) |
| dates.js:16:62:16:66 | taint |
| dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:42:18:64 | datefor ... taint) |
| dates.js:18:59:18:63 | taint |
| express.js:7:15:7:33 | req.param("wobble") |
| express.js:7:15:7:33 | req.param("wobble") |
| express.js:7:15:7:33 | req.param("wobble") |
@@ -125,6 +151,14 @@ nodes
| jquery.js:16:38:16:52 | window.location |
| jquery.js:16:38:16:52 | window.location |
| jquery.js:16:38:16:63 | window. ... tring() |
| jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") |
| jwt-server.js:7:17:7:35 | req.param("wobble") |
| jwt-server.js:9:16:9:20 | taint |
| jwt-server.js:9:55:9:61 | decoded |
| jwt-server.js:11:19:11:25 | decoded |
| jwt-server.js:11:19:11:29 | decoded.foo |
| jwt-server.js:11:19:11:29 | decoded.foo |
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message |
@@ -688,6 +722,31 @@ edges
| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `<span ... <span>` |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint |
| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint |
| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint |
| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint |
| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint |
| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint |
| dates.js:9:36:9:50 | window.location | dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:50 | window.location | dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) |
| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) |
| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) |
| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) |
| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) |
| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) |
| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) |
| express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") |
| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted |
| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted |
@@ -716,6 +775,13 @@ edges
| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() |
| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) |
| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) |
| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded |
| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded |
| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo |
| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
@@ -1179,6 +1245,11 @@ edges
| classnames.js:11:31:11:79 | `<span ... <span>` | classnames.js:10:45:10:55 | window.name | classnames.js:11:31:11:79 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:10:45:10:55 | window.name | user-provided value |
| classnames.js:13:31:13:83 | `<span ... <span>` | classnames.js:13:57:13:67 | window.name | classnames.js:13:31:13:83 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:13:57:13:67 | window.name | user-provided value |
| classnames.js:15:31:15:78 | `<span ... <span>` | classnames.js:15:52:15:62 | window.name | classnames.js:15:31:15:78 | `<span ... <span>` | Cross-site scripting vulnerability due to $@. | classnames.js:15:52:15:62 | window.name | user-provided value |
| dates.js:11:31:11:70 | `Time i ... aint)}` | dates.js:9:36:9:50 | window.location | dates.js:11:31:11:70 | `Time i ... aint)}` | Cross-site scripting vulnerability due to $@. | dates.js:9:36:9:50 | window.location | user-provided value |
| dates.js:12:31:12:73 | `Time i ... aint)}` | dates.js:9:36:9:50 | window.location | dates.js:12:31:12:73 | `Time i ... aint)}` | Cross-site scripting vulnerability due to $@. | dates.js:9:36:9:50 | window.location | user-provided value |
| dates.js:13:31:13:72 | `Time i ... time)}` | dates.js:9:36:9:50 | window.location | dates.js:13:31:13:72 | `Time i ... time)}` | Cross-site scripting vulnerability due to $@. | dates.js:9:36:9:50 | window.location | user-provided value |
| dates.js:16:31:16:69 | `Time i ... aint)}` | dates.js:9:36:9:50 | window.location | dates.js:16:31:16:69 | `Time i ... aint)}` | Cross-site scripting vulnerability due to $@. | dates.js:9:36:9:50 | window.location | user-provided value |
| dates.js:18:31:18:66 | `Time i ... aint)}` | dates.js:9:36:9:50 | window.location | dates.js:18:31:18:66 | `Time i ... aint)}` | Cross-site scripting vulnerability due to $@. | dates.js:9:36:9:50 | window.location | user-provided value |
| express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | Cross-site scripting vulnerability due to $@. | express.js:7:15:7:33 | req.param("wobble") | user-provided value |
| jquery.js:7:5:7:34 | "<div i ... + "\\">" | jquery.js:2:17:2:40 | documen ... .search | jquery.js:7:5:7:34 | "<div i ... + "\\">" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value |
| jquery.js:8:18:8:34 | "XSS: " + tainted | jquery.js:2:17:2:33 | document.location | 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 |
@@ -1186,6 +1257,7 @@ edges
| jquery.js:14:19:14:58 | decodeU ... n.hash) | jquery.js:14:38:14:52 | window.location | jquery.js:14:19:14:58 | decodeU ... n.hash) | Cross-site scripting vulnerability due to $@. | jquery.js:14:38:14:52 | window.location | user-provided value |
| jquery.js:15:19:15:60 | decodeU ... search) | jquery.js:15:38:15:52 | window.location | jquery.js:15:19:15:60 | decodeU ... search) | Cross-site scripting vulnerability due to $@. | jquery.js:15:38:15:52 | window.location | user-provided value |
| jquery.js:16:19:16:64 | decodeU ... ring()) | jquery.js:16:38:16:52 | window.location | jquery.js:16:19:16:64 | decodeU ... ring()) | Cross-site scripting vulnerability due to $@. | jquery.js:16:38:16:52 | window.location | user-provided value |
| jwt-server.js:11:19:11:29 | decoded.foo | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:11:19:11:29 | decoded.foo | Cross-site scripting vulnerability due to $@. | jwt-server.js:7:17:7:35 | req.param("wobble") | user-provided value |
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | HTML injection vulnerability due to $@. | nodemailer.js:13:50:13:66 | req.query.message | user-provided value |
| optionalSanitizer.js:6:18:6:23 | target | optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:6:18:6:23 | target | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:32 | document.location | user-provided value |
| optionalSanitizer.js:9:18:9:24 | tainted | optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:9:18:9:24 | tainted | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:32 | document.location | user-provided value |

View File

@@ -89,6 +89,32 @@ nodes
| classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name |
| classnames.js:15:52:15:62 | window.name |
| dates.js:9:9:9:69 | taint |
| dates.js:9:17:9:69 | decodeU ... ing(1)) |
| dates.js:9:36:9:50 | window.location |
| dates.js:9:36:9:50 | window.location |
| dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:68 | window. ... ring(1) |
| dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:42:11:68 | dateFns ... taint) |
| dates.js:11:63:11:67 | taint |
| dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:42:12:71 | dateFns ... taint) |
| dates.js:12:66:12:70 | taint |
| dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:42:13:70 | dateFns ... )(time) |
| dates.js:13:59:13:63 | taint |
| dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:42:16:67 | moment( ... (taint) |
| dates.js:16:62:16:66 | taint |
| dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:42:18:64 | datefor ... taint) |
| dates.js:18:59:18:63 | taint |
| express.js:7:15:7:33 | req.param("wobble") |
| express.js:7:15:7:33 | req.param("wobble") |
| express.js:7:15:7:33 | req.param("wobble") |
@@ -125,6 +151,21 @@ nodes
| jquery.js:16:38:16:52 | window.location |
| jquery.js:16:38:16:52 | window.location |
| jquery.js:16:38:16:63 | window. ... tring() |
| jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") |
| jwt-server.js:7:17:7:35 | req.param("wobble") |
| jwt-server.js:9:16:9:20 | taint |
| jwt-server.js:9:55:9:61 | decoded |
| jwt-server.js:11:19:11:25 | decoded |
| jwt-server.js:11:19:11:29 | decoded.foo |
| jwt-server.js:11:19:11:29 | decoded.foo |
| jwt.js:4:36:4:39 | data |
| jwt.js:4:36:4:39 | data |
| jwt.js:5:9:5:34 | decoded |
| jwt.js:5:19:5:34 | jwt_decode(data) |
| jwt.js:5:30:5:33 | data |
| jwt.js:6:14:6:20 | decoded |
| jwt.js:6:14:6:20 | decoded |
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message |
@@ -692,6 +733,31 @@ edges
| classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `<span ... <span>` |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) |
| dates.js:9:9:9:69 | taint | dates.js:11:63:11:67 | taint |
| dates.js:9:9:9:69 | taint | dates.js:12:66:12:70 | taint |
| dates.js:9:9:9:69 | taint | dates.js:13:59:13:63 | taint |
| dates.js:9:9:9:69 | taint | dates.js:16:62:16:66 | taint |
| dates.js:9:9:9:69 | taint | dates.js:18:59:18:63 | taint |
| dates.js:9:17:9:69 | decodeU ... ing(1)) | dates.js:9:9:9:69 | taint |
| dates.js:9:36:9:50 | window.location | dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:50 | window.location | dates.js:9:36:9:55 | window.location.hash |
| dates.js:9:36:9:55 | window.location.hash | dates.js:9:36:9:68 | window. ... ring(1) |
| dates.js:9:36:9:68 | window. ... ring(1) | dates.js:9:17:9:69 | decodeU ... ing(1)) |
| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:42:11:68 | dateFns ... taint) | dates.js:11:31:11:70 | `Time i ... aint)}` |
| dates.js:11:63:11:67 | taint | dates.js:11:42:11:68 | dateFns ... taint) |
| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:42:12:71 | dateFns ... taint) | dates.js:12:31:12:73 | `Time i ... aint)}` |
| dates.js:12:66:12:70 | taint | dates.js:12:42:12:71 | dateFns ... taint) |
| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:42:13:70 | dateFns ... )(time) | dates.js:13:31:13:72 | `Time i ... time)}` |
| dates.js:13:59:13:63 | taint | dates.js:13:42:13:70 | dateFns ... )(time) |
| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:42:16:67 | moment( ... (taint) | dates.js:16:31:16:69 | `Time i ... aint)}` |
| dates.js:16:62:16:66 | taint | dates.js:16:42:16:67 | moment( ... (taint) |
| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:42:18:64 | datefor ... taint) | dates.js:18:31:18:66 | `Time i ... aint)}` |
| dates.js:18:59:18:63 | taint | dates.js:18:42:18:64 | datefor ... taint) |
| express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") |
| jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted |
| jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted |
@@ -720,6 +786,19 @@ edges
| jquery.js:16:38:16:52 | window.location | jquery.js:16:38:16:63 | window. ... tring() |
| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) |
| jquery.js:16:38:16:63 | window. ... tring() | jquery.js:16:19:16:64 | decodeU ... ring()) |
| jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint |
| jwt-server.js:9:16:9:20 | taint | jwt-server.js:9:55:9:61 | decoded |
| jwt-server.js:9:55:9:61 | decoded | jwt-server.js:11:19:11:25 | decoded |
| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo |
| jwt-server.js:11:19:11:25 | decoded | jwt-server.js:11:19:11:29 | decoded.foo |
| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data |
| jwt.js:4:36:4:39 | data | jwt.js:5:30:5:33 | data |
| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded |
| jwt.js:5:9:5:34 | decoded | jwt.js:6:14:6:20 | decoded |
| jwt.js:5:19:5:34 | jwt_decode(data) | jwt.js:5:9:5:34 | decoded |
| jwt.js:5:30:5:33 | data | jwt.js:5:19:5:34 | jwt_decode(data) |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
@@ -1165,4 +1244,5 @@ edges
| winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) |
| winjs.js:2:17:2:53 | documen ... ring(1) | winjs.js:2:7:2:53 | tainted |
#select
| jwt.js:6:14:6:20 | decoded | jwt.js:4:36:4:39 | data | jwt.js:6:14:6:20 | decoded | Cross-site scripting vulnerability due to $@. | jwt.js:4:36:4:39 | data | user-provided value |
| typeahead.js:10:16:10:18 | loc | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | Cross-site scripting vulnerability due to $@. | typeahead.js:9:28:9:30 | loc | user-provided value |

View File

@@ -0,0 +1,19 @@
import dateFns from 'date-fns';
import dateFnsFp from 'date-fns/fp';
import dateFnsEsm from 'date-fns/esm';
import moment from 'moment';
import dateformat from 'dateformat';
function main() {
let time = new Date();
let taint = decodeURIComponent(window.location.hash.substring(1));
document.body.innerHTML = `Time is ${dateFns.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsEsm.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsFp.format(taint)(time)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFns.format(taint, time)}`; // OK - time arg is safe
document.body.innerHTML = `Time is ${dateFnsFp.format(time)(taint)}`; // OK - time arg is safe
document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${moment(taint).format()}`; // OK
document.body.innerHTML = `Time is ${dateformat(time, taint)}`; // NOT OK
}

View File

@@ -0,0 +1,13 @@
var express = require('express');
var app = express();
import jwt from "jsonwebtoken";
import { JSDOM } from "jsdom";
app.get('/some/path', function (req, res) {
var taint = req.param("wobble");
jwt.verify(taint, 'my-secret-key', function (err, decoded) {
// NOT OK
new JSDOM(decoded.foo, { runScripts: "dangerously" });
});
});

View File

@@ -0,0 +1,7 @@
import jwt_decode from "jwt-decode";
import $ from "jquery"
$.post(loginUrl(), {data: "foo"}, (data, xhr) => {
var decoded = jwt_decode(data);
$.jGrowl(decoded); // NOT OK - but only flagged with additional sources [INCONSISTENCY]
});

View File

@@ -208,6 +208,11 @@ nodes
| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') |
| HardcodedCredentials.js:237:47:237:54 | username |
| HardcodedCredentials.js:237:47:237:71 | usernam ... assword |
| HardcodedCredentials.js:245:9:245:44 | privateKey |
| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" |
| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" |
| HardcodedCredentials.js:246:42:246:51 | privateKey |
| HardcodedCredentials.js:246:42:246:51 | privateKey |
edges
| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' |
| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' |
@@ -309,6 +314,10 @@ edges
| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') |
| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword |
| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) |
| HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey |
| HardcodedCredentials.js:245:9:245:44 | privateKey | HardcodedCredentials.js:246:42:246:51 | privateKey |
| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey |
| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:9:245:44 | privateKey |
#select
| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name |
| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | password |
@@ -374,3 +383,4 @@ edges
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | authorization header |
| HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:245:22:245:44 | "myHard ... ateKey" | HardcodedCredentials.js:246:42:246:51 | privateKey | The hard-coded value "myHardCodedPrivateKey" is used as $@. | HardcodedCredentials.js:246:42:246:51 | privateKey | key |

View File

@@ -237,4 +237,16 @@
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
},
});
})
})
(function () {
import jwt from "jsonwebtoken";
var privateKey = "myHardCodedPrivateKey";
var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'});
var publicKey = "myHardCodedPublicKey";
jwt.verify(token, publicKey, function(err, decoded) {
console.log(decoded);
});
})();