Merge branch 'main' into regexpParse

This commit is contained in:
Erik Krogh Kristensen
2020-11-13 09:33:16 +01:00
268 changed files with 4220 additions and 1629 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,6 +79,7 @@ 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

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

@@ -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

@@ -212,8 +212,10 @@ private predicate isRequire(DataFlow::Node nd) {
imp.getImportedPath().getValue() = "module"
|
baseObj =
[DataFlow::destructuredModuleImportNode(imp),
DataFlow::valueNode(imp.getASpecifier().(ImportNamespaceSpecifier))] and
[
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

@@ -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

@@ -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

@@ -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") |
@@ -688,6 +714,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 |
@@ -1179,6 +1230,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 |

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") |
@@ -692,6 +718,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 |

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
}