mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge branch 'main' into js/shared-dataflow-merge-main
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
"": {
|
||||
"name": "typescript-parser-wrapper",
|
||||
"dependencies": {
|
||||
"typescript": "^5.6.2"
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.15.3"
|
||||
@@ -20,9 +20,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
|
||||
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "typescript-parser-wrapper",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"typescript": "5.6.2"
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --project tsconfig.json",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,29 @@
|
||||
## 2.2.0
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals.
|
||||
* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases.
|
||||
* Regular expression related queries now account for unknown flags.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint-steps for `String.prototype.toWellFormed`.
|
||||
* Added taint-steps for `Map.groupBy` and `Object.groupBy`.
|
||||
* Added taint-steps for `Array.prototype.findLast`.
|
||||
* Added taint-steps for `Array.prototype.findLastIndex`.
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint-steps for `Array.prototype.with`.
|
||||
* Added taint-steps for `Array.prototype.toSpliced`
|
||||
* Added taint-steps for `Array.prototype.toReversed`.
|
||||
* Added taint-steps for `Array.prototype.toSorted`.
|
||||
* Added support for `String.prototype.matchAll`.
|
||||
* Added taint-steps for `Array.prototype.reverse`
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Added support for `String.prototype.matchAll`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint-steps for `Array.prototype.reverse`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint-steps for `Array.prototype.toReversed`.
|
||||
* Added taint-steps for `Array.prototype.toSorted`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Added taint-steps for `Array.prototype.toSpliced`
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Added taint-steps for `Array.prototype.with`.
|
||||
10
javascript/ql/lib/change-notes/released/2.1.1.md
Normal file
10
javascript/ql/lib/change-notes/released/2.1.1.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 2.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint-steps for `Array.prototype.with`.
|
||||
* Added taint-steps for `Array.prototype.toSpliced`
|
||||
* Added taint-steps for `Array.prototype.toReversed`.
|
||||
* Added taint-steps for `Array.prototype.toSorted`.
|
||||
* Added support for `String.prototype.matchAll`.
|
||||
* Added taint-steps for `Array.prototype.reverse`
|
||||
14
javascript/ql/lib/change-notes/released/2.2.0.md
Normal file
14
javascript/ql/lib/change-notes/released/2.2.0.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## 2.2.0
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals.
|
||||
* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases.
|
||||
* Regular expression related queries now account for unknown flags.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint-steps for `String.prototype.toWellFormed`.
|
||||
* Added taint-steps for `Map.groupBy` and `Object.groupBy`.
|
||||
* Added taint-steps for `Array.prototype.findLast`.
|
||||
* Added taint-steps for `Array.prototype.findLastIndex`.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 2.1.0
|
||||
lastReleaseVersion: 2.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-all
|
||||
version: 2.1.1-dev
|
||||
version: 2.2.1-dev
|
||||
groups: javascript
|
||||
dbscheme: semmlecode.javascript.dbscheme
|
||||
extractor: javascript
|
||||
|
||||
@@ -384,10 +384,10 @@ private module ArrayLibraries {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a call to `Array.prototype.find` or a polyfill implementing the same functionality.
|
||||
* Gets a call to `Array.prototype.find` or `Array.prototype.findLast` or a polyfill implementing the same functionality.
|
||||
*/
|
||||
DataFlow::CallNode arrayFindCall(DataFlow::Node array) {
|
||||
result.(DataFlow::MethodCallNode).getMethodName() = "find" and
|
||||
result.(DataFlow::MethodCallNode).getMethodName() in ["find", "findLast"] and
|
||||
array = result.getReceiver()
|
||||
or
|
||||
result = DataFlow::moduleImport(["array.prototype.find", "array-find"]).getACall() and
|
||||
@@ -483,4 +483,31 @@ private module ArrayLibraries {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a data flow step that tracks the flow of data through callback functions in arrays.
|
||||
*/
|
||||
private class ArrayCallBackDataFlowStep extends PreCallGraphStep {
|
||||
override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getMethodName() = ["findLast", "find", "findLastIndex"] and
|
||||
prop = arrayLikeElement() and
|
||||
obj = call.getReceiver() and
|
||||
element = call.getCallback(0).getParameter(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This step models the propagation of data from the array to the callback function's parameter.
|
||||
*/
|
||||
private class ArrayCallBackDataTaintStep extends TaintTracking::SharedTaintStep {
|
||||
override predicate step(DataFlow::Node obj, DataFlow::Node element) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getMethodName() = ["findLast", "find", "findLastIndex"] and
|
||||
obj = call.getReceiver() and
|
||||
element = call.getCallback(0).getParameter(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,4 +151,32 @@ private module CollectionDataFlow {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A step for a call to `groupBy` on an iterable object.
|
||||
*/
|
||||
private class GroupByTaintStep extends TaintTracking::SharedTaintStep {
|
||||
override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call = DataFlow::globalVarRef(["Map", "Object"]).getAMemberCall("groupBy") and
|
||||
pred = call.getArgument(0) and
|
||||
(succ = call.getCallback(1).getParameter(0) or succ = call)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A step for handling data flow and taint tracking for the groupBy method on iterable objects.
|
||||
* Ensures propagation of taint and data flow through the groupBy operation.
|
||||
*/
|
||||
private class GroupByDataFlowStep extends PreCallGraphStep {
|
||||
override predicate storeStep(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call = DataFlow::globalVarRef("Map").getAMemberCall("groupBy") and
|
||||
pred = call.getArgument(0) and
|
||||
succ = call and
|
||||
prop = mapValueUnknownKey()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,12 @@ class StringReplaceCall extends DataFlow::MethodCallNode {
|
||||
*/
|
||||
predicate isGlobal() { this.getRegExp().isGlobal() or this.getMethodName() = "replaceAll" }
|
||||
|
||||
/**
|
||||
* Holds if this is a global replacement, that is, the first argument is a regular expression
|
||||
* with the `g` flag or unknown flags, or this is a call to `.replaceAll()`.
|
||||
*/
|
||||
predicate maybeGlobal() { this.getRegExp().maybeGlobal() or this.getMethodName() = "replaceAll" }
|
||||
|
||||
/**
|
||||
* Holds if this call to `replace` replaces `old` with `new`.
|
||||
*/
|
||||
|
||||
@@ -1690,6 +1690,9 @@ class RegExpCreationNode extends DataFlow::SourceNode {
|
||||
/** Holds if the constructed predicate has the `g` flag. */
|
||||
predicate isGlobal() { RegExp::isGlobal(this.getFlags()) }
|
||||
|
||||
/** Holds if the constructed predicate has the `g` flag or unknown flags. */
|
||||
predicate maybeGlobal() { RegExp::maybeGlobal(this.tryGetFlags()) }
|
||||
|
||||
/** Gets a data flow node referring to this regular expression. */
|
||||
private DataFlow::SourceNode getAReference(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
|
||||
@@ -453,7 +453,8 @@ module TaintTracking {
|
||||
"anchor", "big", "blink", "bold", "concat", "fixed", "fontcolor", "fontsize",
|
||||
"italics", "link", "padEnd", "padStart", "repeat", "replace", "replaceAll", "slice",
|
||||
"small", "strike", "sub", "substr", "substring", "sup", "toLocaleLowerCase",
|
||||
"toLocaleUpperCase", "toLowerCase", "toUpperCase", "trim", "trimLeft", "trimRight"
|
||||
"toLocaleUpperCase", "toLowerCase", "toUpperCase", "trim", "trimLeft", "trimRight",
|
||||
"toWellFormed"
|
||||
]
|
||||
or
|
||||
// sorted, interesting, properties of Object.prototype
|
||||
|
||||
@@ -30,7 +30,7 @@ module Cryptography {
|
||||
class PasswordHashingAlgorithm = CryptoAlgorithms::PasswordHashingAlgorithm;
|
||||
|
||||
/**
|
||||
* A data-flow node that is an application of a cryptographic algorithm. For example,
|
||||
* A data flow node that is an application of a cryptographic algorithm. For example,
|
||||
* encryption, decryption, signature-validation.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
@@ -40,7 +40,7 @@ module Cryptography {
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
|
||||
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
DataFlow::Node getInitialization() { result = super.getInitialization() }
|
||||
|
||||
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
||||
@@ -61,14 +61,14 @@ module Cryptography {
|
||||
/** Provides classes for modeling new applications of a cryptographic algorithms. */
|
||||
module CryptographicOperation {
|
||||
/**
|
||||
* A data-flow node that is an application of a cryptographic algorithm. For example,
|
||||
* A data flow node that is an application of a cryptographic algorithm. For example,
|
||||
* encryption, decryption, signature-validation.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `CryptographicOperation` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
/** Gets the data flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
abstract DataFlow::Node getInitialization();
|
||||
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
@@ -118,14 +118,14 @@ module Http {
|
||||
/** Provides classes for modeling HTTP clients. */
|
||||
module Client {
|
||||
/**
|
||||
* A data-flow node that makes an outgoing HTTP request.
|
||||
* A data flow node that makes an outgoing HTTP request.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `Http::Client::Request::Range` instead.
|
||||
*/
|
||||
class Request extends DataFlow::Node instanceof Request::Range {
|
||||
/**
|
||||
* Gets a data-flow node that contributes to the URL of the request.
|
||||
* Gets a data flow node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
|
||||
@@ -150,14 +150,14 @@ module Http {
|
||||
/** Provides a class for modeling new HTTP requests. */
|
||||
module Request {
|
||||
/**
|
||||
* A data-flow node that makes an outgoing HTTP request.
|
||||
* A data flow node that makes an outgoing HTTP request.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `Http::Client::Request` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a data-flow node that contributes to the URL of the request.
|
||||
* Gets a data flow node that contributes to the URL of the request.
|
||||
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
|
||||
*/
|
||||
abstract DataFlow::Node getAUrlPart();
|
||||
|
||||
@@ -74,7 +74,7 @@ private StringReplaceCall getAStringReplaceMethodCall(StringReplaceCall n) {
|
||||
module HtmlSanitization {
|
||||
private predicate fixedGlobalReplacement(StringReplaceCallSequence chain) {
|
||||
forall(StringReplaceCall member | member = chain.getAMember() |
|
||||
member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpLiteralNode
|
||||
member.maybeGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -42,9 +42,12 @@ module CleartextLogging {
|
||||
*/
|
||||
class MaskingReplacer extends Barrier, StringReplaceCall {
|
||||
MaskingReplacer() {
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
exists(this.getRawReplacement().getStringValue()) and
|
||||
any(RegExpDot term).getLiteral() = this.getRegExp().asExpr()
|
||||
exists(DataFlow::RegExpCreationNode regexpObj |
|
||||
this.(StringReplaceCall).getRegExp() = regexpObj and
|
||||
regexpObj.getRoot() = any(RegExpDot term).getRootTerm()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ module PrototypePollutingAssignmentConfig implements DataFlow::StateConfigSig {
|
||||
// Replacing with "_" is likely to be exploitable
|
||||
not replace.getRawReplacement().getStringValue() = "_" and
|
||||
(
|
||||
replace.isGlobal()
|
||||
replace.maybeGlobal()
|
||||
or
|
||||
// Non-global replace with a non-empty string can also prevent __proto__ by
|
||||
// inserting a chunk of text that doesn't fit anywhere in __proto__
|
||||
|
||||
@@ -76,7 +76,7 @@ module RegExpInjection {
|
||||
*/
|
||||
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
|
||||
MetacharEscapeSanitizer() {
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
(
|
||||
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["{", "[", "+"])
|
||||
or
|
||||
|
||||
@@ -360,10 +360,10 @@ module TaintedPath {
|
||||
this instanceof StringReplaceCall and
|
||||
input = this.getReceiver() and
|
||||
output = this and
|
||||
not exists(RegExpLiteral literal, RegExpTerm term |
|
||||
this.(StringReplaceCall).getRegExp().asExpr() = literal and
|
||||
this.(StringReplaceCall).isGlobal() and
|
||||
literal.getRoot() = term
|
||||
not exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term |
|
||||
this.(StringReplaceCall).getRegExp() = regexp and
|
||||
this.(StringReplaceCall).maybeGlobal() and
|
||||
regexp.getRoot() = term
|
||||
|
|
||||
term.getAMatchedString() = "/" or
|
||||
term.getAMatchedString() = "." or
|
||||
@@ -444,9 +444,9 @@ module TaintedPath {
|
||||
input = this.getReceiver() and
|
||||
output = this and
|
||||
this.isGlobal() and
|
||||
exists(RegExpLiteral literal, RegExpTerm term |
|
||||
this.getRegExp().asExpr() = literal and
|
||||
literal.getRoot() = term and
|
||||
exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term |
|
||||
this.getRegExp() = regexp and
|
||||
regexp.getRoot() = term and
|
||||
not term.getAMatchedString() = "/"
|
||||
|
|
||||
term.getAMatchedString() = "." or
|
||||
|
||||
@@ -266,7 +266,7 @@ module UnsafeShellCommandConstruction {
|
||||
class ReplaceQuotesSanitizer extends Sanitizer, StringReplaceCall {
|
||||
ReplaceQuotesSanitizer() {
|
||||
this.getAReplacedString() = "'" and
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
this.getRawReplacement().mayHaveStringValue(["'\\''", ""])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ module Shared {
|
||||
*/
|
||||
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
|
||||
MetacharEscapeSanitizer() {
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
(
|
||||
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["<", "'", "\""])
|
||||
or
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.2.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.2.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.2.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -23,7 +23,7 @@ string metachar() { result = "'\"\\&<>\n\r\t*|{}[]%$".charAt(_) }
|
||||
|
||||
/** Gets a string matched by `e` in a `replace` call. */
|
||||
string getAMatchedString(DataFlow::Node e) {
|
||||
result = e.(DataFlow::RegExpLiteralNode).getRoot().getAMatchedString()
|
||||
result = e.(DataFlow::RegExpCreationNode).getRoot().getAMatchedString()
|
||||
or
|
||||
result = e.getStringValue()
|
||||
}
|
||||
@@ -52,8 +52,8 @@ predicate isSimpleAlt(RegExpAlt t) { forall(RegExpTerm ch | ch = t.getAChild() |
|
||||
* Holds if `mce` is of the form `x.replace(re, new)`, where `re` is a global
|
||||
* regular expression and `new` prefixes the matched string with a backslash.
|
||||
*/
|
||||
predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpLiteralNode re) {
|
||||
mce.isGlobal() and
|
||||
predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpCreationNode re) {
|
||||
mce.maybeGlobal() and
|
||||
re = mce.getRegExp() and
|
||||
(
|
||||
// replacement with `\$&`, `\$1` or similar
|
||||
@@ -72,7 +72,7 @@ predicate allBackslashesEscaped(DataFlow::Node nd) {
|
||||
nd instanceof JsonStringifyCall
|
||||
or
|
||||
// check whether `nd` itself escapes backslashes
|
||||
exists(DataFlow::RegExpLiteralNode rel | isBackslashEscape(nd, rel) |
|
||||
exists(DataFlow::RegExpCreationNode rel | isBackslashEscape(nd, rel) |
|
||||
// if it's a complex regexp, we conservatively assume that it probably escapes backslashes
|
||||
not isSimple(rel.getRoot()) or
|
||||
getAMatchedString(rel) = "\\"
|
||||
@@ -143,12 +143,21 @@ predicate whitelistedRemoval(StringReplaceCall repl) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a nice string representation of the pattern or value of the node.
|
||||
*/
|
||||
string getPatternOrValueString(DataFlow::Node node) {
|
||||
if node instanceof DataFlow::RegExpConstructorInvokeNode
|
||||
then result = "/" + node.(DataFlow::RegExpConstructorInvokeNode).getRoot() + "/"
|
||||
else result = node.toString()
|
||||
}
|
||||
|
||||
from StringReplaceCall repl, DataFlow::Node old, string msg
|
||||
where
|
||||
(old = repl.getArgument(0) or old = repl.getRegExp()) and
|
||||
(
|
||||
not repl.isGlobal() and
|
||||
msg = "This replaces only the first occurrence of " + old + "." and
|
||||
not repl.maybeGlobal() and
|
||||
msg = "This replaces only the first occurrence of " + getPatternOrValueString(old) + "." and
|
||||
// only flag if this is likely to be a sanitizer or URL encoder or decoder
|
||||
exists(string m | m = getAMatchedString(old) |
|
||||
// sanitizer
|
||||
|
||||
@@ -65,8 +65,8 @@ predicate isCaseSensitiveMiddleware(
|
||||
arg = call.getArgument(0) and
|
||||
regexp.getAReference().flowsTo(arg) and
|
||||
exists(string flags |
|
||||
flags = regexp.getFlags() and
|
||||
not RegExp::isIgnoreCase(flags)
|
||||
flags = regexp.tryGetFlags() and
|
||||
not RegExp::maybeIgnoreCase(flags)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ predicate hasNonVoidCallbackMethod(string name) {
|
||||
name =
|
||||
[
|
||||
"every", "filter", "find", "findIndex", "flatMap", "map", "reduce", "reduceRight", "some",
|
||||
"sort"
|
||||
"sort", "findLastIndex", "findLast"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
3
javascript/ql/src/change-notes/released/1.2.4.md
Normal file
3
javascript/ql/src/change-notes/released/1.2.4.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.2.4
|
||||
|
||||
No user-facing changes.
|
||||
3
javascript/ql/src/change-notes/released/1.2.5.md
Normal file
3
javascript/ql/src/change-notes/released/1.2.5.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.2.5
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.3
|
||||
lastReleaseVersion: 1.2.5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-queries
|
||||
version: 1.2.4-dev
|
||||
version: 1.2.6-dev
|
||||
groups:
|
||||
- javascript
|
||||
- queries
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import javascript
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().getStringValue() = "source" or
|
||||
source.(DataFlow::CallNode).getCalleeName() = "source"
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import javascript
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().getStringValue() = "source" or
|
||||
source.(DataFlow::CallNode).getCalleeName() = "source"
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink = any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument()
|
||||
|
||||
@@ -108,4 +108,41 @@
|
||||
var arr8_spread = [];
|
||||
arr8_spread = arr8_spread.toSpliced(0, 0, ...arr);
|
||||
sink(arr8_spread.pop()); // NOT OK
|
||||
|
||||
sink(arr.findLast(someCallback)); // NOT OK
|
||||
|
||||
{ // Test for findLast function
|
||||
const list = ["source"];
|
||||
const element = list.findLast((item) => sink(item)); // NOT OK
|
||||
sink(element); // NOT OK
|
||||
}
|
||||
|
||||
{ // Test for find function
|
||||
const list = ["source"];
|
||||
const element = list.find((item) => sink(item)); // NOT OK
|
||||
sink(element); // NOT OK
|
||||
}
|
||||
|
||||
{ // Test for findLastIndex function
|
||||
const list = ["source"];
|
||||
const element = list.findLastIndex((item) => sink(item)); // NOT OK
|
||||
sink(element); // OK
|
||||
}
|
||||
{
|
||||
const arr = source();
|
||||
const element1 = arr.find((item) => sink(item)); // NOT OK
|
||||
sink(element1); // NOT OK
|
||||
}
|
||||
|
||||
{
|
||||
const arr = source();
|
||||
const element1 = arr.findLast((item) => sink(item)); // NOT OK
|
||||
sink(element1); // NOT OK
|
||||
}
|
||||
|
||||
{
|
||||
const arr = source();
|
||||
const element1 = arr.findLastIndex((item) => sink(item)); // NOT OK
|
||||
sink(element1); // OK
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,4 +5,3 @@ ambiguousPreferredPredecessor
|
||||
| pack2/main.js:1:1:3:1 | def moduleImport("pack2").getMember("exports").getMember("MainClass").getInstance() |
|
||||
ambiguousSinkName
|
||||
ambiguousFunctionName
|
||||
failures
|
||||
|
||||
@@ -2,7 +2,7 @@ import javascript
|
||||
import semmle.javascript.RestrictedLocations
|
||||
import semmle.javascript.Lines
|
||||
import semmle.javascript.endpoints.EndpointNaming as EndpointNaming
|
||||
import testUtilities.InlineExpectationsTest
|
||||
import utils.test.InlineExpectationsTest
|
||||
import EndpointNaming::Debug
|
||||
|
||||
private predicate isIgnored(DataFlow::FunctionNode function) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr().getStringValue() = "source" }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
API::Node testInstance() { result = API::moduleImport("@example/test").getInstance() }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import javascript
|
||||
private import semmle.javascript.heuristics.AdditionalSources
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof HeuristicSource }
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
function test() {
|
||||
let x = source();
|
||||
sink(x.toWellFormed()); // NOT OK
|
||||
|
||||
const wellFormedX = x.toWellFormed();
|
||||
sink(wellFormedX); // NOT OK
|
||||
|
||||
const concatWellFormedX = "/" + wellFormedX + "!";
|
||||
sink(concatWellFormedX); // NOT OK
|
||||
|
||||
sink(source().toWellFormed()); // NOT OK
|
||||
}
|
||||
@@ -69,6 +69,34 @@ function test() {
|
||||
const xReversed = x.toReversed();
|
||||
sink(xReversed) // NOT OK
|
||||
|
||||
sink(Map.groupBy(x, z => z)); // NOT OK
|
||||
sink(Custom.groupBy(x, z => z)); // OK
|
||||
sink(Object.groupBy(x, z => z)); // NOT OK
|
||||
sink(Map.groupBy(source(), (item) => sink(item))); // NOT OK
|
||||
|
||||
{
|
||||
const grouped = Map.groupBy(x, (item) => sink(item)); // NOT OK
|
||||
sink(grouped); // NOT OK
|
||||
}
|
||||
{
|
||||
const list = [source()];
|
||||
const grouped = Map.groupBy(list, (item) => sink(item)); // NOT OK
|
||||
sink(grouped); // NOT OK
|
||||
}
|
||||
{
|
||||
const data = source();
|
||||
const result = Object.groupBy(data, item => item);
|
||||
const taintedValue = result[notDefined()];
|
||||
sink(taintedValue); // NOT OK
|
||||
}
|
||||
{
|
||||
const data = source();
|
||||
const map = Map.groupBy(data, item => item);
|
||||
const taintedValue = map.get(true);
|
||||
sink(taintedValue); // NOT OK
|
||||
sink(map.get(true)); // NOT OK
|
||||
}
|
||||
|
||||
sink(x.with()) // NOT OK
|
||||
const xWith = x.with();
|
||||
sink(xWith) // NOT OK
|
||||
|
||||
@@ -1877,8 +1877,35 @@ nodes
|
||||
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | semmle.label | [MethodCallExpr] obj[key ... rCase() |
|
||||
| tst.ts:508:21:508:23 | [VarRef] key | semmle.label | [VarRef] key |
|
||||
| tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.label | [Label] toUpperCase |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.label | [NamespaceDeclaration] namespa ... type. } |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | semmle.order | 92 |
|
||||
| tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | [VarDecl] TS57 |
|
||||
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | [DeclStmt] const a = ... |
|
||||
| tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | [VarDecl] a |
|
||||
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | [VariableDeclarator] a: symbol |
|
||||
| tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol |
|
||||
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | [ExportDeclaration] export ... }; } |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | [ClassDefinition,TypeDefinition] class A ... }; } |
|
||||
| tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | [VarDecl] A |
|
||||
| tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
|
||||
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
|
||||
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
|
||||
| tst.ts:515:18:515:17 | [Label] constructor | semmle.label | [Label] constructor |
|
||||
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } |
|
||||
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | [FunctionExpr] [a]() { return 1 } |
|
||||
| tst.ts:516:8:516:8 | [VarRef] a | semmle.label | [VarRef] a |
|
||||
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | [BlockStmt] { return 1 } |
|
||||
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | [ReturnStmt] return 1 |
|
||||
| tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | [Literal] 1 |
|
||||
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | [DeclStmt] const e1 = ... |
|
||||
| tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | [VarDecl] e1 |
|
||||
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | [VariableDeclarator] e1: A[typeof a] |
|
||||
| tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | [LocalTypeAccess] A |
|
||||
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | [IndexedAccessTypeExpr] A[typeof a] |
|
||||
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | [TypeofTypeExpr] typeof a |
|
||||
| tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | [LocalVarTypeAccess] a |
|
||||
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
|
||||
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 92 |
|
||||
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 |
|
||||
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
|
||||
| tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS |
|
||||
| tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
|
||||
@@ -1896,7 +1923,7 @@ nodes
|
||||
| tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
|
||||
| tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
|
||||
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
|
||||
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 93 |
|
||||
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 94 |
|
||||
| tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
|
||||
| tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES |
|
||||
| tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
|
||||
@@ -1914,7 +1941,7 @@ nodes
|
||||
| tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
|
||||
| tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
|
||||
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
|
||||
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 94 |
|
||||
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 |
|
||||
| tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
|
||||
| tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
|
||||
| tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' |
|
||||
@@ -1922,7 +1949,7 @@ nodes
|
||||
| tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; |
|
||||
| tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' |
|
||||
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
|
||||
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 95 |
|
||||
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 |
|
||||
| tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
|
||||
| tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
|
||||
| tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' |
|
||||
@@ -1930,7 +1957,7 @@ nodes
|
||||
| tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; |
|
||||
| tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' |
|
||||
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
|
||||
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 96 |
|
||||
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 97 |
|
||||
| tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
|
||||
| tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
|
||||
| tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' |
|
||||
@@ -1938,16 +1965,16 @@ nodes
|
||||
| tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; |
|
||||
| tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' |
|
||||
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; |
|
||||
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 97 |
|
||||
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 98 |
|
||||
| type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B |
|
||||
| type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean |
|
||||
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... |
|
||||
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 98 |
|
||||
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 99 |
|
||||
| type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b |
|
||||
| type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B |
|
||||
| type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B |
|
||||
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; |
|
||||
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 99 |
|
||||
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 100 |
|
||||
| type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray |
|
||||
| type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T |
|
||||
| type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T |
|
||||
@@ -1959,14 +1986,14 @@ nodes
|
||||
| type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray<T> | semmle.label | [GenericTypeExpr] ValueOrArray<T> |
|
||||
| type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
|
||||
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... |
|
||||
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 100 |
|
||||
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 101 |
|
||||
| type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c |
|
||||
| type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> |
|
||||
| type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray |
|
||||
| type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray<number> | semmle.label | [GenericTypeExpr] ValueOrArray<number> |
|
||||
| type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
|
||||
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; |
|
||||
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 101 |
|
||||
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 102 |
|
||||
| type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json |
|
||||
| type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] |
|
||||
| type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
|
||||
@@ -1982,12 +2009,12 @@ nodes
|
||||
| type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
|
||||
| type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] |
|
||||
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... |
|
||||
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 102 |
|
||||
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 103 |
|
||||
| type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json |
|
||||
| type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json |
|
||||
| type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
|
||||
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; |
|
||||
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 103 |
|
||||
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 104 |
|
||||
| type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode |
|
||||
| type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] |
|
||||
| type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
|
||||
@@ -2003,7 +2030,7 @@ nodes
|
||||
| type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
|
||||
| type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] |
|
||||
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... |
|
||||
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 104 |
|
||||
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 105 |
|
||||
| type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode |
|
||||
| type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] |
|
||||
| type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
|
||||
@@ -2028,12 +2055,12 @@ nodes
|
||||
| type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" |
|
||||
| type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" |
|
||||
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
|
||||
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 105 |
|
||||
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 106 |
|
||||
| type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
|
||||
| type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
|
||||
| type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
|
||||
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} |
|
||||
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 106 |
|
||||
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 107 |
|
||||
| type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} |
|
||||
| type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C |
|
||||
| type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
|
||||
@@ -2041,36 +2068,36 @@ nodes
|
||||
| type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
|
||||
| type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor |
|
||||
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... |
|
||||
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 107 |
|
||||
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 108 |
|
||||
| type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj |
|
||||
| type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C |
|
||||
| type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C |
|
||||
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} |
|
||||
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 108 |
|
||||
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 109 |
|
||||
| type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} |
|
||||
| type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E |
|
||||
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... |
|
||||
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 109 |
|
||||
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 110 |
|
||||
| type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj |
|
||||
| type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E |
|
||||
| type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E |
|
||||
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} |
|
||||
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 110 |
|
||||
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 111 |
|
||||
| type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} |
|
||||
| type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N |
|
||||
| type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; |
|
||||
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... |
|
||||
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 111 |
|
||||
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 112 |
|
||||
| type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj |
|
||||
| type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N |
|
||||
| type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N |
|
||||
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
|
||||
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 112 |
|
||||
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 113 |
|
||||
| type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
|
||||
| type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
|
||||
| type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
|
||||
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } |
|
||||
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 113 |
|
||||
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 114 |
|
||||
| type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I |
|
||||
| type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S |
|
||||
| type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S |
|
||||
@@ -2078,14 +2105,14 @@ nodes
|
||||
| type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; |
|
||||
| type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S |
|
||||
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... |
|
||||
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 114 |
|
||||
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 115 |
|
||||
| type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i |
|
||||
| type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I<number> | semmle.label | [VariableDeclarator] i: I<number> |
|
||||
| type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I |
|
||||
| type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I<number> | semmle.label | [GenericTypeExpr] I<number> |
|
||||
| type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
|
||||
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } |
|
||||
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 115 |
|
||||
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 116 |
|
||||
| type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C |
|
||||
| type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
|
||||
| type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
|
||||
@@ -2097,14 +2124,14 @@ nodes
|
||||
| type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T |
|
||||
| type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
|
||||
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... |
|
||||
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 116 |
|
||||
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 117 |
|
||||
| type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c |
|
||||
| type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C<number> | semmle.label | [VariableDeclarator] c: C<number> |
|
||||
| type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C |
|
||||
| type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C<number> | semmle.label | [GenericTypeExpr] C<number> |
|
||||
| type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
|
||||
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } |
|
||||
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 117 |
|
||||
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 118 |
|
||||
| type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color |
|
||||
| type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red |
|
||||
| type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red |
|
||||
@@ -2113,29 +2140,29 @@ nodes
|
||||
| type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue |
|
||||
| type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue |
|
||||
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... |
|
||||
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 118 |
|
||||
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 119 |
|
||||
| type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color |
|
||||
| type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color |
|
||||
| type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color |
|
||||
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } |
|
||||
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 119 |
|
||||
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 120 |
|
||||
| type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember |
|
||||
| type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member |
|
||||
| type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member |
|
||||
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... |
|
||||
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 120 |
|
||||
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 121 |
|
||||
| type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e |
|
||||
| type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember |
|
||||
| type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember |
|
||||
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; |
|
||||
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 121 |
|
||||
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 122 |
|
||||
| type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias |
|
||||
| type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T |
|
||||
| type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T |
|
||||
| type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
|
||||
| type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] |
|
||||
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... |
|
||||
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 122 |
|
||||
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 123 |
|
||||
| type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray |
|
||||
| type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> |
|
||||
| type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias |
|
||||
@@ -5534,6 +5561,56 @@ edges
|
||||
| tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | tst.ts:508:26:508:36 | [Label] toUpperCase | semmle.order | 2 |
|
||||
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.label | 0 |
|
||||
| tst.ts:508:17:508:38 | [MethodCallExpr] obj[key ... rCase() | tst.ts:508:17:508:36 | [DotExpr] obj[key].toUpperCase | semmle.order | 0 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.label | 1 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:513:11:513:14 | [VarDecl] TS57 | semmle.order | 1 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.label | 2 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:514:3:514:26 | [DeclStmt] const a = ... | semmle.order | 2 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.label | 3 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | semmle.order | 3 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.label | 4 |
|
||||
| tst.ts:513:1:520:1 | [NamespaceDeclaration] namespa ... type. } | tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | semmle.order | 4 |
|
||||
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.label | 1 |
|
||||
| tst.ts:514:3:514:26 | [DeclStmt] const a = ... | tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | semmle.order | 1 |
|
||||
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.label | 1 |
|
||||
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:17:514:17 | [VarDecl] a | semmle.order | 1 |
|
||||
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.label | 2 |
|
||||
| tst.ts:514:17:514:25 | [VariableDeclarator] a: symbol | tst.ts:514:20:514:25 | [KeywordTypeExpr] symbol | semmle.order | 2 |
|
||||
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.label | 1 |
|
||||
| tst.ts:515:3:517:3 | [ExportDeclaration] export ... }; } | tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | semmle.order | 1 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.label | 1 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:16:515:16 | [VarDecl] A | semmle.order | 1 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.label | 3 |
|
||||
| tst.ts:515:10:517:3 | [ClassDefinition,TypeDefinition] class A ... }; } | tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | semmle.order | 3 |
|
||||
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.label | 2 |
|
||||
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [FunctionExpr] () {} | semmle.order | 2 |
|
||||
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.label | 1 |
|
||||
| tst.ts:515:18:515:17 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:515:18:515:17 | [Label] constructor | semmle.order | 1 |
|
||||
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.label | 5 |
|
||||
| tst.ts:515:18:515:17 | [FunctionExpr] () {} | tst.ts:515:18:515:17 | [BlockStmt] {} | semmle.order | 5 |
|
||||
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.label | 1 |
|
||||
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | semmle.order | 1 |
|
||||
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.label | 2 |
|
||||
| tst.ts:516:7:516:24 | [ClassInitializedMember,MethodDefinition] [a]() { return 1 } | tst.ts:516:8:516:8 | [VarRef] a | semmle.order | 2 |
|
||||
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.label | 5 |
|
||||
| tst.ts:516:7:516:24 | [FunctionExpr] [a]() { return 1 } | tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | semmle.order | 5 |
|
||||
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.label | 1 |
|
||||
| tst.ts:516:13:516:24 | [BlockStmt] { return 1 } | tst.ts:516:15:516:22 | [ReturnStmt] return 1 | semmle.order | 1 |
|
||||
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.label | 1 |
|
||||
| tst.ts:516:15:516:22 | [ReturnStmt] return 1 | tst.ts:516:22:516:22 | [Literal] 1 | semmle.order | 1 |
|
||||
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.label | 1 |
|
||||
| tst.ts:519:3:519:32 | [DeclStmt] const e1 = ... | tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | semmle.order | 1 |
|
||||
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.label | 1 |
|
||||
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:17:519:18 | [VarDecl] e1 | semmle.order | 1 |
|
||||
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.label | 2 |
|
||||
| tst.ts:519:17:519:31 | [VariableDeclarator] e1: A[typeof a] | tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | semmle.order | 2 |
|
||||
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.label | 1 |
|
||||
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:21:519:21 | [LocalTypeAccess] A | semmle.order | 1 |
|
||||
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.label | 2 |
|
||||
| tst.ts:519:21:519:31 | [IndexedAccessTypeExpr] A[typeof a] | tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | semmle.order | 2 |
|
||||
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.label | 1 |
|
||||
| tst.ts:519:23:519:30 | [TypeofTypeExpr] typeof a | tst.ts:519:30:519:30 | [LocalVarTypeAccess] a | semmle.order | 1 |
|
||||
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 |
|
||||
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 |
|
||||
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 |
|
||||
|
||||
@@ -728,6 +728,13 @@ getExprType
|
||||
| tst.ts:508:17:508:38 | obj[key ... rCase() | string |
|
||||
| tst.ts:508:21:508:23 | key | string |
|
||||
| tst.ts:508:26:508:36 | toUpperCase | () => string |
|
||||
| tst.ts:513:11:513:14 | TS57 | typeof TS57 in tst.ts |
|
||||
| tst.ts:514:17:514:17 | a | symbol |
|
||||
| tst.ts:515:16:515:16 | A | A |
|
||||
| tst.ts:516:7:516:24 | [a]() { return 1 } | () => number |
|
||||
| tst.ts:516:8:516:8 | a | symbol |
|
||||
| tst.ts:516:22:516:22 | 1 | 1 |
|
||||
| tst.ts:519:17:519:18 | e1 | () => number |
|
||||
| tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" |
|
||||
| tstModuleCJS.cts:2:12:2:15 | Math | Math |
|
||||
| tstModuleCJS.cts:2:12:2:22 | Math.random | () => number |
|
||||
@@ -843,6 +850,7 @@ getTypeDefinitionType
|
||||
| tst.ts:447:5:458:5 | class P ... }\\n } | Person |
|
||||
| tst.ts:473:5:476:5 | class S ... ;\\n } | SomeClass |
|
||||
| tst.ts:481:5:481:34 | type Pa ... T, T]; | Pair3<T> |
|
||||
| tst.ts:515:10:517:3 | class A ... };\\n } | A |
|
||||
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
|
||||
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
|
||||
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
|
||||
@@ -1219,6 +1227,11 @@ getTypeExprType
|
||||
| tst.ts:506:27:506:32 | string | string |
|
||||
| tst.ts:506:35:506:41 | unknown | unknown |
|
||||
| tst.ts:506:50:506:55 | string | string |
|
||||
| tst.ts:514:20:514:25 | symbol | symbol |
|
||||
| tst.ts:519:21:519:21 | A | A |
|
||||
| tst.ts:519:21:519:31 | A[typeof a] | () => number |
|
||||
| tst.ts:519:23:519:30 | typeof a | symbol |
|
||||
| tst.ts:519:30:519:30 | a | symbol |
|
||||
| tstModuleCJS.cts:1:33:1:35 | 'a' | "a" |
|
||||
| tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" |
|
||||
| tstModuleCJS.cts:1:39:1:41 | 'b' | "b" |
|
||||
@@ -1290,6 +1303,7 @@ getTypeExprType
|
||||
missingToString
|
||||
referenceDefinition
|
||||
| A | badTypes.ts:5:1:5:29 | interfa ... is.B {} |
|
||||
| A | tst.ts:515:10:517:3 | class A ... };\\n } |
|
||||
| Action | tst.ts:252:3:254:50 | type Ac ... ring }; |
|
||||
| Alias<T> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
|
||||
| Alias<number> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
|
||||
|
||||
@@ -508,4 +508,13 @@ module TS55 {
|
||||
var str = obj[key].toUpperCase(); // Now okay, previously was error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace TS57{
|
||||
declare const a: symbol;
|
||||
export class A {
|
||||
[a]() { return 1 };
|
||||
}
|
||||
|
||||
declare const e1: A[typeof a]; // Now okay, previously was compilation error TS2538: Type 'symbol' cannot be used as an index type.
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss
|
||||
import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery as ServerSideUrlRedirect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node.(DataFlow::CallNode).getCalleeName() = "source" }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.frameworks.data.internal.ApiGraphModels as ApiGraphModels
|
||||
|
||||
class TypeModelFromCodeQL extends ModelInput::TypeModel {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
import testUtilities.InlineExpectationsTest
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.TaintedPathQuery
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
deprecated class TaintedPathConsistency extends ConsistencyConfiguration {
|
||||
TaintedPathConsistency() { this = "TaintedPathConsistency" }
|
||||
|
||||
@@ -197,3 +197,25 @@ var server = http.createServer(function(req, res) {
|
||||
cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK
|
||||
cp.execFileSync("foobar", {cwd: path}); // NOT OK
|
||||
});
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
let path = url.parse(req.url, true).query.path;
|
||||
|
||||
// Removal of forward-slash or dots.
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK.
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to.
|
||||
});
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
let path = url.parse(req.url, true).query.path;
|
||||
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute)
|
||||
|
||||
if (!pathModule.isAbsolute(path)) {
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK
|
||||
res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.TemplateObjectInjectionQuery
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.CommandInjectionQuery as CommandInjection
|
||||
import semmle.javascript.security.dataflow.IndirectCommandInjectionQuery as IndirectCommandInjection
|
||||
import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery as ShellCommandInjectionFromEnvironment
|
||||
|
||||
@@ -628,3 +628,14 @@ module.exports.veryIndeirect = function (name) {
|
||||
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
}
|
||||
|
||||
module.exports.sanitizer = function (name) {
|
||||
var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'"
|
||||
cp.exec("rm -rf " + sanitized); // NOT OK
|
||||
|
||||
var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'"
|
||||
cp.exec("rm -rf " + sanitized); // OK
|
||||
|
||||
var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'"
|
||||
cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives.
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.DomBasedXssQuery
|
||||
|
||||
deprecated class ConsistencyConfig extends ConsistencyConfiguration {
|
||||
|
||||
@@ -503,3 +503,10 @@ function Foo() {
|
||||
};
|
||||
Object.assign(this, obj);
|
||||
}
|
||||
|
||||
function nonGlobalSanitizer() {
|
||||
var target = document.location.search
|
||||
$("#foo").html(target.replace(new RegExp("<|>"), '')); // NOT OK
|
||||
$("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK -- most likely good. We don't know what the flags are.
|
||||
$("#foo").html(target.replace(new RegExp("<|>", "g"), '')); // OK
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.ReflectedXssQuery as ReflectedXss
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.StoredXssQuery as StoredXss
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.UnsafeHtmlConstructionQuery as UnsafeHtmlConstruction
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery as UnsafeJqueryPlugin
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.XssThroughDomQuery
|
||||
|
||||
deprecated class ConsistencyConfig extends ConsistencyConfiguration {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection
|
||||
import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
| tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here |
|
||||
| tst.js:68:10:70:38 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:68:10:69:39 | s.repla ... apos;") | here |
|
||||
| tst.js:79:10:79:66 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:79:10:79:43 | s.repla ... epl[c]) | here |
|
||||
| tst.js:99:10:101:49 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:99:10:100:51 | s.repla ... apos;") | here |
|
||||
|
||||
@@ -94,3 +94,21 @@ function testWithCapturedVar(x) {
|
||||
function encodeDecodeEncode(s) {
|
||||
return goodEncode(goodDecode(goodEncode(s)));
|
||||
}
|
||||
|
||||
function badEncode(s) {
|
||||
return s.replace(new RegExp("\"", "g"), """)
|
||||
.replace(new RegExp("\'", "g"), "'")
|
||||
.replace(new RegExp("&", "g"), "&"); // NOT OK
|
||||
}
|
||||
|
||||
function goodEncode(s) {
|
||||
return s.replace(new RegExp("\"", ""), """)
|
||||
.replace(new RegExp("\'", ""), "'")
|
||||
.replace(new RegExp("&", ""), "&"); // OK
|
||||
}
|
||||
|
||||
function goodEncode(s) {
|
||||
return s.replace(new RegExp("\"", unknownFlags()), """)
|
||||
.replace(new RegExp("\'", unknownFlags()), "'")
|
||||
.replace(new RegExp("&", unknownFlags()), "&"); // OK
|
||||
}
|
||||
|
||||
@@ -65,3 +65,9 @@
|
||||
| tst.js:305:10:305:34 | s().rep ... ]/g,'') | This HTML sanitizer does not sanitize double quotes |
|
||||
| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
|
||||
| tst.js:320:9:329:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
|
||||
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands |
|
||||
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes |
|
||||
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes |
|
||||
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize ampersands |
|
||||
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize double quotes |
|
||||
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize single quotes |
|
||||
|
||||
@@ -39,3 +39,4 @@
|
||||
| tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < | <script |
|
||||
| tst-multi-character-sanitization.js:148:3:148:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:148:41:148:41 | < | <script |
|
||||
| tst-multi-character-sanitization.js:152:3:152:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:152:41:152:41 | < | <script |
|
||||
| tst.js:341:9:341:44 | p.repla ... "), "") | This string may still contain $@, which may cause a path injection vulnerability. | tst.js:341:31:341:33 | \\. | ../ |
|
||||
|
||||
@@ -29,3 +29,9 @@
|
||||
| tst.js:149:2:149:24 | x.repla ... replace | This replaces only the first occurrence of "\\n". |
|
||||
| tst.js:193:9:193:17 | s.replace | This replaces only the first occurrence of /'/. |
|
||||
| tst.js:202:10:202:18 | p.replace | This replaces only the first occurrence of "/../". |
|
||||
| tst.js:341:9:341:17 | p.replace | This replaces only the first occurrence of /\\.\\.//. |
|
||||
| tst.js:345:9:345:17 | s.replace | This does not escape backslash characters in the input. |
|
||||
| tst.js:349:9:349:17 | s.replace | This replaces only the first occurrence of /'/. |
|
||||
| tst.js:353:9:353:17 | s.replace | This does not escape backslash characters in the input. |
|
||||
| tst.js:362:2:362:10 | x.replace | This replaces only the first occurrence of /\n/. |
|
||||
| tst.js:363:2:363:24 | x.repla ... replace | This replaces only the first occurrence of /\n/. |
|
||||
|
||||
@@ -327,4 +327,41 @@ function incompleteComplexSanitizers() {
|
||||
if (str === "\"")
|
||||
return """;
|
||||
}) + '"';
|
||||
}
|
||||
}
|
||||
|
||||
function typicalBadHtmlSanitizers(s) {
|
||||
s().replace(new RegExp("[<>]", "g"),''); // NOT OK
|
||||
}
|
||||
|
||||
function typicalBadHtmlSanitizers(s) {
|
||||
s().replace(new RegExp("[<>]", unknown()),''); // NOT OK
|
||||
}
|
||||
|
||||
function bad18NewRegExp(p) {
|
||||
return p.replace(new RegExp("\\.\\./"), ""); // NOT OK
|
||||
}
|
||||
|
||||
function bad4NewRegExpG(s) {
|
||||
return s.replace(new RegExp("\'","g"), "\\$&"); // NOT OK
|
||||
}
|
||||
|
||||
function bad4NewRegExp(s) {
|
||||
return s.replace(new RegExp("\'"), "\\$&"); // NOT OK
|
||||
}
|
||||
|
||||
function bad4NewRegExpUnknown(s) {
|
||||
return s.replace(new RegExp("\'", unknownFlags()), "\\$&"); // NOT OK
|
||||
}
|
||||
|
||||
function newlinesNewReGexp(s) {
|
||||
require("child_process").execSync("which emacs").toString().replace(new RegExp("\n"), ""); // OK
|
||||
|
||||
x.replace(new RegExp("\n", "g"), "").replace(x, y); // OK
|
||||
x.replace(x, y).replace(new RegExp("\n", "g"), ""); // OK
|
||||
|
||||
x.replace(new RegExp("\n"), "").replace(x, y); // NOT OK
|
||||
x.replace(x, y).replace(new RegExp("\n"), ""); // NOT OK
|
||||
|
||||
x.replace(new RegExp("\n", unknownFlags()), "").replace(x, y); // OK
|
||||
x.replace(x, y).replace(new RegExp("\n", unknownFlags()), ""); // OK
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
| tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
|
||||
| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
|
||||
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:73:1:74:2 | app.get ... ware\\n}) | case-insensitive path |
|
||||
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path |
|
||||
| tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path |
|
||||
| tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path |
|
||||
| tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path |
|
||||
|
||||
@@ -93,3 +93,16 @@ app.use(/\/summonerByName|\/currentGame/,apiLimit1, apiLimit2);
|
||||
app.get('/currentGame', function (req, res) {
|
||||
res.send("FOO");
|
||||
});
|
||||
|
||||
app.get(
|
||||
new RegExp('^/bar(.*)?', unknownFlag()), // OK - Might be OK if the unknown flag evaluates to case insensitive one
|
||||
unknown(),
|
||||
function(req, res, next) {
|
||||
if (req.params.blah) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/bar/*', (req, res) => { // OK - not a middleware
|
||||
});
|
||||
|
||||
@@ -175,3 +175,11 @@ const debug = require('debug')('test');
|
||||
const myPasscode = foo();
|
||||
console.log(myPasscode); // NOT OK
|
||||
});
|
||||
|
||||
(function () {
|
||||
console.log(password.replace(/./g, "*")); // OK
|
||||
console.log(password.replace(new RegExp(".", "g"), "*")); // OK
|
||||
console.log(password.replace(new RegExp("."), "*")); // NOT OK
|
||||
console.log(password.replace(new RegExp(".", unknownFlags()), "*")); // OK -- Most likely not a problem.
|
||||
console.log(password.replace(new RegExp("pre_._suf", "g"), "*")); // OK
|
||||
})();
|
||||
|
||||
@@ -130,6 +130,9 @@
|
||||
| polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G |
|
||||
| polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
|
||||
| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X |
|
||||
| polynomial-redos.js:140:33:140:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
|
||||
| polynomial-redos.js:141:33:141:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
|
||||
| polynomial-redos.js:142:33:142:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
|
||||
| regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) |
|
||||
| regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) |
|
||||
| regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) |
|
||||
|
||||
@@ -136,4 +136,8 @@ app.use(function(req, res) {
|
||||
modified3.replace(/hh+I/g, "b"); // NOT OK
|
||||
|
||||
tainted.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*X/); // NOT OK
|
||||
|
||||
modified3.replace(new RegExp("hh+I", "g"), "b"); // NOT OK
|
||||
modified3.replace(new RegExp("hh+I", unknownFlags()), "b"); // NOT OK
|
||||
modified3.replace(new RegExp("hh+I", ""), "b"); // NOT OK
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.UnsafeDeserializationQuery
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
query: Security/CWE-611/Xxe.ql
|
||||
postprocess: testUtilities/InlineExpectationsTestQuery.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -92,3 +92,16 @@ app.get("argv", function(req, res) {
|
||||
|
||||
new RegExp(`^${process.argv[1]}/Foo/bar.app$`); // NOT OK
|
||||
});
|
||||
|
||||
app.get("argv", function(req, res) {
|
||||
var input = req.param("input");
|
||||
|
||||
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]"), "\\$&");
|
||||
new RegExp(sanitized); // NOT OK
|
||||
|
||||
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", "g"), "\\$&");
|
||||
new RegExp(sanitized); // OK
|
||||
|
||||
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", unknownFlags()), "\\$&");
|
||||
new RegExp(sanitized); // OK -- Most likely not a problem.
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.ResourceExhaustionQuery
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import javascript
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
import semmle.javascript.security.dataflow.PrototypePollutingAssignmentQuery
|
||||
|
||||
deprecated class Config extends ConsistencyConfiguration {
|
||||
|
||||
@@ -123,3 +123,10 @@ app.get('/assign', (req, res) => {
|
||||
Object.assign(dest, plainObj[taint]);
|
||||
dest[taint] = taint; // OK - 'dest' is not Object.prototype itself (but possibly a copy)
|
||||
});
|
||||
|
||||
app.get('/foo', (req, res) => {
|
||||
let obj = {};
|
||||
obj[req.query.x.replace(new RegExp('_', 'g'), '')].x = 'foo'; // OK
|
||||
obj[req.query.x.replace(new RegExp('_', ''), '')].x = 'foo'; // NOT OK
|
||||
obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.RequestForgeryQuery as RequestForgery
|
||||
import semmle.javascript.security.dataflow.ClientSideRequestForgeryQuery as ClientSideRequestForgery
|
||||
deprecated import testUtilities.ConsistencyChecking
|
||||
deprecated import utils.test.ConsistencyChecking
|
||||
|
||||
query predicate resultInWrongFile(DataFlow::Node node) {
|
||||
exists(string filePattern |
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
| tst.js:53:10:53:34 | bothOnl ... fects() | the $@ does not return anything, yet the return value is used. | tst.js:48:2:50:5 | functio ... )\\n } | function onlySideEffects2 |
|
||||
| tst.js:76:12:76:46 | [1,2,3] ... n, 3)}) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:76:27:76:45 | n => {equals(n, 3)} | callback function |
|
||||
| tst.js:80:12:80:50 | filter( ... 3) } ) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:80:28:80:48 | x => { ... x, 3) } | callback function |
|
||||
| tst.js:114:12:114:56 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLastIndex is used. | tst.js:114:34:114:55 | n => { ... , 3); } | callback function |
|
||||
| tst.js:117:12:117:51 | [1,2,3] ... 3); }) | the $@ does not return anything, yet the return value from the call to findLast is used. | tst.js:117:29:117:50 | n => { ... , 3); } | callback function |
|
||||
|
||||
@@ -107,3 +107,13 @@ class Bar extends Foo {
|
||||
console.log(super()); // OK.
|
||||
}
|
||||
}
|
||||
|
||||
() => {
|
||||
let equals = (x, y) => { return x === y; };
|
||||
|
||||
var foo = [1,2,3].findLastIndex(n => { equals(n, 3); }) // NOT OK
|
||||
console.log(foo);
|
||||
|
||||
var foo = [1,2,3].findLast(n => { equals(n, 3); }) // NOT OK
|
||||
console.log(foo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user