mirror of
https://github.com/github/codeql.git
synced 2026-05-21 06:37:10 +02:00
Compare commits
4 Commits
tombolton/
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74ed89409c | ||
|
|
58a2597c3a | ||
|
|
c5d917eb72 | ||
|
|
f25fc70b7c |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -52,12 +52,6 @@
|
||||
java/ql/test/stubs/**/*.java linguist-generated=true
|
||||
java/ql/test/experimental/stubs/**/*.java linguist-generated=true
|
||||
|
||||
# For some languages, upgrade script testing references really old dbscheme
|
||||
# files from legacy upgrades that have CRLF line endings. Since upgrade
|
||||
# resolution relies on object hashes, we must suppress line ending conversion
|
||||
# for those testing dbscheme files.
|
||||
*/ql/lib/upgrades/initial/*.dbscheme -text
|
||||
|
||||
# Generated test files - these are synced from the standard JavaScript libraries using
|
||||
# `javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py`.
|
||||
javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/**/*.js linguist-generated=true -merge
|
||||
|
||||
3
.github/workflows/check-change-note.yml
vendored
3
.github/workflows/check-change-note.yml
vendored
@@ -6,11 +6,8 @@ on:
|
||||
paths:
|
||||
- "*/ql/src/**/*.ql"
|
||||
- "*/ql/src/**/*.qll"
|
||||
- "*/ql/lib/**/*.ql"
|
||||
- "*/ql/lib/**/*.qll"
|
||||
- "!**/experimental/**"
|
||||
- "!ql/**"
|
||||
- ".github/workflows/check-change-note.yml"
|
||||
|
||||
jobs:
|
||||
check-change-note:
|
||||
|
||||
4
.github/workflows/ql-for-ql-build.yml
vendored
4
.github/workflows/ql-for-ql-build.yml
vendored
@@ -31,13 +31,13 @@ jobs:
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
|
||||
- name: Build query pack
|
||||
if: steps.cache-queries.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd ql/ql/src
|
||||
"${CODEQL}" pack create
|
||||
cd .codeql/pack/codeql/ql/0.0.0
|
||||
cd .codeql/pack/codeql/ql-all/0.0.0
|
||||
zip "${PACKZIP}" -r .
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
|
||||
29
.github/workflows/validate-change-notes.yml
vendored
29
.github/workflows/validate-change-notes.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Validate change notes
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "*/ql/*/change-notes/**/*"
|
||||
- ".github/workflows/validate-change-notes.yml"
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
pull_request:
|
||||
paths:
|
||||
- "*/ql/*/change-notes/**/*"
|
||||
- ".github/workflows/validate-change-notes.yml"
|
||||
|
||||
jobs:
|
||||
check-change-note:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
|
||||
- name: Fail if there are any errors with existing change notes
|
||||
|
||||
run: |
|
||||
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.0.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/world-writable-file-creation` query now only detects `open` and `openat` calls with the `O_CREAT` or `O_TMPFILE` flag.
|
||||
2
cpp/ql/lib/change-notes/released/0.0.9.md
Normal file
2
cpp/ql/lib/change-notes/released/0.0.9.md
Normal file
@@ -0,0 +1,2 @@
|
||||
## 0.0.9
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,17 @@
|
||||
## 0.0.9
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new query, `cpp/open-call-with-mode-argument`, to detect when `open` or `openat` is called with the `O_CREAT` or `O_TMPFILE` flag but when the `mode` argument is omitted.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query has been further improved to reduce false positive results, and upgraded from `medium` to `high` precision.
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query now finds more results, where a password is stored in a struct field or class member variable.
|
||||
* The `cpp/cleartext-storage-file` query has been improved, removing false positives where data is written to a standard output stream.
|
||||
* The `cpp/cleartext-storage-buffer` query has been updated to use the `semmle.code.cpp.dataflow.TaintTracking` library.
|
||||
* The `cpp/world-writable-file-creation` query now only detects `open` and `openat` calls with the `O_CREAT` or `O_TMPFILE` flag.
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### New Queries
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query now finds more results, where a password is stored in a struct field or class member variable.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/cleartext-storage-buffer` query has been updated to use the `semmle.code.cpp.dataflow.TaintTracking` library.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/cleartext-storage-file` query has been improved, removing false positives where data is written to a standard output stream.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query, `cpp/open-call-with-mode-argument`, to detect when `open` or `openat` is called with the `O_CREAT` or `O_TMPFILE` flag but when the `mode` argument is omitted.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query has been further improved to reduce false positive results, and upgraded from `medium` to `high` precision.
|
||||
13
cpp/ql/src/change-notes/released/0.0.9.md
Normal file
13
cpp/ql/src/change-notes/released/0.0.9.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## 0.0.9
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new query, `cpp/open-call-with-mode-argument`, to detect when `open` or `openat` is called with the `O_CREAT` or `O_TMPFILE` flag but when the `mode` argument is omitted.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query has been further improved to reduce false positive results, and upgraded from `medium` to `high` precision.
|
||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query now finds more results, where a password is stored in a struct field or class member variable.
|
||||
* The `cpp/cleartext-storage-file` query has been improved, removing false positives where data is written to a standard output stream.
|
||||
* The `cpp/cleartext-storage-buffer` query has been updated to use the `semmle.code.cpp.dataflow.TaintTracking` library.
|
||||
* The `cpp/world-writable-file-creation` query now only detects `open` and `openat` calls with the `O_CREAT` or `O_TMPFILE` flag.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Semmle.Extraction
|
||||
/// <summary>
|
||||
/// The compression algorithm used for trap files.
|
||||
/// </summary>
|
||||
public TrapWriter.CompressionMode TrapCompression { get; set; } = TrapWriter.CompressionMode.Brotli;
|
||||
public TrapWriter.CompressionMode TrapCompression { get; set; } = TrapWriter.CompressionMode.Gzip;
|
||||
|
||||
public virtual bool HandleOption(string key, string value)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.0.3
|
||||
|
||||
## 1.0.2
|
||||
|
||||
## 1.0.0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.0.3
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.0.2
|
||||
lastReleaseVersion: 1.0.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.0.3-dev
|
||||
version: 1.0.3
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.0.3
|
||||
|
||||
## 1.0.2
|
||||
|
||||
## 1.0.0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.0.3
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.0.2
|
||||
lastReleaseVersion: 1.0.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.0.3-dev
|
||||
version: 1.0.3
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -6,7 +6,7 @@ groups:
|
||||
dependencies:
|
||||
codeql/csharp-all: "*"
|
||||
codeql/csharp-queries: "*"
|
||||
codeql/csharp-solorigate-all: "*"
|
||||
codeql/csharp-solorigate-queries: "*"
|
||||
codeql/charp-solorigate-all: "*"
|
||||
codeql/charp-solorigate-queries: "*"
|
||||
extractor: csharp
|
||||
tests: .
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
## 0.0.9
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Added support for C# 10 lambda improvements
|
||||
* Explicit return types on lambda expressions.
|
||||
* Lambda expression can be tagged with method and return value attributes.
|
||||
* Added support for C# 10 [Extended property patterns](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10#extended-property-patterns).
|
||||
* Return value attributes are extracted.
|
||||
* The QL `Attribute` class now has subclasses for each kind of attribute.
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `codeql/csharp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/csharp-all` CodeQL pack.
|
||||
* The `codeql/csharp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/charp-all` CodeQL pack.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Return value attributes are extracted.
|
||||
* The QL `Attribute` class now has subclasses for each kind of attribute.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added support for C# 10 [Extended property patterns](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10#extended-property-patterns).
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
Added support for C# 10 lambda improvements
|
||||
* Explicit return types on lambda expressions.
|
||||
* Lambda expression can be tagged with method and return value attributes.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `codeql/csharp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/csharp-all` CodeQL pack.
|
||||
* The `codeql/csharp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/charp-all` CodeQL pack.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
|
||||
10
csharp/ql/lib/change-notes/released/0.0.9.md
Normal file
10
csharp/ql/lib/change-notes/released/0.0.9.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 0.0.9
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
Added support for C# 10 lambda improvements
|
||||
* Explicit return types on lambda expressions.
|
||||
* Lambda expression can be tagged with method and return value attributes.
|
||||
* Added support for C# 10 [Extended property patterns](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10#extended-property-patterns).
|
||||
* Return value attributes are extracted.
|
||||
* The QL `Attribute` class now has subclasses for each kind of attribute.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -32,20 +32,12 @@ class Guard extends Expr {
|
||||
isGuardedByNode(cfn, this, sub, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `cfn` is guarded by this expression having value `v`.
|
||||
*
|
||||
* Note: This predicate is inlined.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate controlsNode(ControlFlow::Nodes::ElementNode cfn, AbstractValue v) {
|
||||
guardControls(this, cfn.getBasicBlock(), v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if basic block `bb` is guarded by this expression having value `v`.
|
||||
*/
|
||||
predicate controlsBasicBlock(BasicBlock bb, AbstractValue v) { guardControls(this, bb, v) }
|
||||
predicate controlsBasicBlock(BasicBlock bb, AbstractValue v) {
|
||||
Internal::guardControls(this, bb, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this guard is an equality test between `e1` and `e2`. If the test is
|
||||
@@ -54,7 +46,7 @@ class Guard extends Expr {
|
||||
*/
|
||||
predicate isEquality(Expr e1, Expr e2, boolean polarity) {
|
||||
exists(BooleanValue v |
|
||||
this = getAnEqualityCheck(e1, v, e2) and
|
||||
this = Internal::getAnEqualityCheck(e1, v, e2) and
|
||||
polarity = v.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -177,19 +177,6 @@ private predicate isNullDefaultArgument(Ssa::ExplicitDefinition def, AlwaysNullE
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `edef` is an implicit entry definition for a captured variable that
|
||||
* may be guarded, because a call to the capturing callable is guarded.
|
||||
*/
|
||||
private predicate isMaybeGuardedCapturedDef(Ssa::ImplicitEntryDefinition edef) {
|
||||
exists(Ssa::ExplicitDefinition def, ControlFlow::Nodes::ElementNode c, G::Guard g, NullValue nv |
|
||||
def.isCapturedVariableDefinitionFlowIn(edef, c, _) and
|
||||
g = def.getARead() and
|
||||
g.controlsNode(c, nv) and
|
||||
nv.isNonNull()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `def` is an SSA definition that may be `null`. */
|
||||
private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) {
|
||||
not nonNullDef(def) and
|
||||
@@ -227,7 +214,6 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason)
|
||||
exists(Dereference d | dereferenceAt(_, _, def, d) |
|
||||
d.hasNullableType() and
|
||||
not def instanceof Ssa::PhiNode and
|
||||
not isMaybeGuardedCapturedDef(def) and
|
||||
reason = def.getSourceVariable().getAssignable() and
|
||||
msg = "because it has a nullable type"
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
## 0.0.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
## 0.0.7
|
||||
|
||||
1
csharp/ql/src/change-notes/released/0.0.9.md
Normal file
1
csharp/ql/src/change-notes/released/0.0.9.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.9
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -9,9 +9,9 @@ public class E
|
||||
long[][] a2 = null;
|
||||
var haveA2 = ix < len && (a2 = a1[ix]) != null;
|
||||
long[] a3 = null;
|
||||
var haveA3 = haveA2 && (a3 = a2[ix]) != null; // GOOD (FALSE POSITIVE)
|
||||
var haveA3 = haveA2 && (a3 = a2[ix]) != null; // GOOD (false positive)
|
||||
if (haveA3)
|
||||
a3[0] = 0; // GOOD (FALSE POSITIVE)
|
||||
a3[0] = 0; // GOOD (false positive)
|
||||
}
|
||||
|
||||
public void Ex2(bool x, bool y)
|
||||
@@ -24,7 +24,7 @@ public class E
|
||||
s2 = (s1 == null) ? null : "";
|
||||
}
|
||||
if (s2 != null)
|
||||
s1.ToString(); // GOOD (FALSE POSITIVE)
|
||||
s1.ToString(); // GOOD (false positive)
|
||||
}
|
||||
|
||||
public void Ex3(IEnumerable<string> ss)
|
||||
@@ -58,7 +58,7 @@ public class E
|
||||
slice = new List<string>();
|
||||
result.Add(slice);
|
||||
}
|
||||
slice.Add(str); // GOOD (FALSE POSITIVE)
|
||||
slice.Add(str); // GOOD (false positive)
|
||||
++index;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class E
|
||||
arrLen = arr == null ? 0 : arr.Length;
|
||||
|
||||
if (arrLen > 0)
|
||||
arr[0] = 0; // GOOD (FALSE POSITIVE)
|
||||
arr[0] = 0; // GOOD (false positive)
|
||||
}
|
||||
|
||||
public const int MY_CONST_A = 1;
|
||||
@@ -109,7 +109,7 @@ public class E
|
||||
arr2 = new int[arr1.Length];
|
||||
|
||||
for (var i = 0; i < arr1.Length; i++)
|
||||
arr2[i] = arr1[i]; // GOOD (FALSE POSITIVE)
|
||||
arr2[i] = arr1[i]; // GOOD (false positive)
|
||||
}
|
||||
|
||||
public void Ex8(int x, int lim)
|
||||
@@ -122,7 +122,7 @@ public class E
|
||||
int j = 0;
|
||||
while (!stop && j < lim)
|
||||
{
|
||||
int step = (j * obj.GetHashCode()) % 10; // GOOD (FALSE POSITIVE)
|
||||
int step = (j * obj.GetHashCode()) % 10; // GOOD (false positive)
|
||||
if (step == 0)
|
||||
{
|
||||
obj.ToString(); // GOOD
|
||||
@@ -156,7 +156,7 @@ public class E
|
||||
cond = true;
|
||||
}
|
||||
if (cond)
|
||||
obj2.ToString(); // GOOD (FALSE POSITIVE)
|
||||
obj2.ToString(); // GOOD (false positive)
|
||||
}
|
||||
|
||||
public void Ex10(int[] a)
|
||||
@@ -164,7 +164,7 @@ public class E
|
||||
int n = a == null ? 0 : a.Length;
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
int x = a[i]; // GOOD (FALSE POSITIVE)
|
||||
int x = a[i]; // GOOD (false positive)
|
||||
if (x > 7)
|
||||
a = new int[n];
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class E
|
||||
bool b2 = obj == null ? false : b1;
|
||||
if (b2 == null)
|
||||
{
|
||||
obj.ToString(); // GOOD (FALSE POSITIVE)
|
||||
obj.ToString(); // GOOD (false positive)
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
@@ -183,7 +183,7 @@ public class E
|
||||
}
|
||||
if (b1 == null)
|
||||
{
|
||||
obj.ToString(); // GOOD (FALSE POSITIVE)
|
||||
obj.ToString(); // GOOD (false positive)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ public class E
|
||||
if (o is string)
|
||||
{
|
||||
var s = o as string;
|
||||
return s.Length; // GOOD (FALSE POSITIVE)
|
||||
return s.Length; // GOOD (false positive)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -383,7 +383,7 @@ public class E
|
||||
return false;
|
||||
if (e1 == null && e2 == null)
|
||||
return true;
|
||||
return e1.Long == e2.Long; // GOOD (FALSE POSITIVE)
|
||||
return e1.Long == e2.Long; // GOOD (false positive)
|
||||
}
|
||||
|
||||
int Ex38(int? i)
|
||||
@@ -411,26 +411,6 @@ public class E
|
||||
i ??= null;
|
||||
return i.Value; // GOOD
|
||||
}
|
||||
|
||||
static bool Ex42(int? i, IEnumerable<int> @is)
|
||||
{
|
||||
return @is.Any(j => j == i.Value); // BAD (maybe)
|
||||
}
|
||||
|
||||
static bool Ex43(int? i, IEnumerable<int> @is)
|
||||
{
|
||||
if (i.HasValue)
|
||||
return @is.Any(j => j == i.Value); // GOOD
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Ex44(int? i, IEnumerable<int> @is)
|
||||
{
|
||||
if (i.HasValue)
|
||||
@is = @is.Where(j => j == i.Value); // BAD (always) (FALSE NEGATIVE)
|
||||
i = null;
|
||||
return @is.Any();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Extensions
|
||||
|
||||
@@ -238,12 +238,6 @@
|
||||
| E.cs:384:27:384:36 | ... == ... | true | E.cs:384:33:384:36 | null | E.cs:384:27:384:28 | access to parameter e2 |
|
||||
| E.cs:386:16:386:33 | ... == ... | true | E.cs:386:16:386:22 | access to property Long | E.cs:386:27:386:33 | access to property Long |
|
||||
| E.cs:386:16:386:33 | ... == ... | true | E.cs:386:27:386:33 | access to property Long | E.cs:386:16:386:22 | access to property Long |
|
||||
| E.cs:417:29:417:40 | ... == ... | true | E.cs:417:29:417:29 | access to parameter j | E.cs:417:34:417:40 | access to property Value |
|
||||
| E.cs:417:29:417:40 | ... == ... | true | E.cs:417:34:417:40 | access to property Value | E.cs:417:29:417:29 | access to parameter j |
|
||||
| E.cs:423:33:423:44 | ... == ... | true | E.cs:423:33:423:33 | access to parameter j | E.cs:423:38:423:44 | access to property Value |
|
||||
| E.cs:423:33:423:44 | ... == ... | true | E.cs:423:38:423:44 | access to property Value | E.cs:423:33:423:33 | access to parameter j |
|
||||
| E.cs:430:34:430:45 | ... == ... | true | E.cs:430:34:430:34 | access to parameter j | E.cs:430:39:430:45 | access to property Value |
|
||||
| E.cs:430:34:430:45 | ... == ... | true | E.cs:430:39:430:45 | access to property Value | E.cs:430:34:430:34 | access to parameter j |
|
||||
| Forwarding.cs:59:13:59:21 | ... == ... | true | Forwarding.cs:59:13:59:13 | access to parameter o | Forwarding.cs:59:18:59:21 | null |
|
||||
| Forwarding.cs:59:13:59:21 | ... == ... | true | Forwarding.cs:59:18:59:21 | null | Forwarding.cs:59:13:59:13 | access to parameter o |
|
||||
| Forwarding.cs:78:16:78:39 | call to method ReferenceEquals | true | Forwarding.cs:78:32:78:32 | access to parameter o | Forwarding.cs:78:35:78:38 | null |
|
||||
|
||||
@@ -1292,14 +1292,6 @@
|
||||
| E.cs:411:9:411:18 | ... ?? ... | null | E.cs:411:15:411:18 | null | null |
|
||||
| E.cs:412:16:412:16 | access to local variable i | non-null | E.cs:411:9:411:18 | ... ?? ... | non-null |
|
||||
| E.cs:412:16:412:16 | access to local variable i | null | E.cs:411:9:411:18 | ... ?? ... | null |
|
||||
| E.cs:417:16:417:41 | call to method Any<Int32> | true | E.cs:417:16:417:18 | access to parameter is | non-empty |
|
||||
| E.cs:422:13:422:22 | access to property HasValue | false | E.cs:422:13:422:13 | access to parameter i | null |
|
||||
| E.cs:422:13:422:22 | access to property HasValue | true | E.cs:422:13:422:13 | access to parameter i | non-null |
|
||||
| E.cs:423:20:423:45 | call to method Any<Int32> | true | E.cs:423:20:423:22 | access to parameter is | non-empty |
|
||||
| E.cs:429:13:429:22 | access to property HasValue | false | E.cs:429:13:429:13 | access to parameter i | null |
|
||||
| E.cs:429:13:429:22 | access to property HasValue | true | E.cs:429:13:429:13 | access to parameter i | non-null |
|
||||
| E.cs:432:16:432:24 | call to method Any<Int32> | false | E.cs:432:16:432:18 | access to parameter is | empty |
|
||||
| E.cs:432:16:432:24 | call to method Any<Int32> | true | E.cs:432:16:432:18 | access to parameter is | non-empty |
|
||||
| Forwarding.cs:9:13:9:30 | !... | false | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | true |
|
||||
| Forwarding.cs:9:13:9:30 | !... | true | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | false |
|
||||
| Forwarding.cs:9:14:9:14 | access to local variable s | empty | Forwarding.cs:7:20:7:23 | null | empty |
|
||||
|
||||
@@ -294,10 +294,6 @@
|
||||
| E.cs:404:9:404:9 | access to local variable i | E.cs:404:9:404:9 | access to local variable i | null | true |
|
||||
| E.cs:411:9:411:9 | access to local variable i | E.cs:411:9:411:9 | access to local variable i | non-null | false |
|
||||
| E.cs:411:9:411:9 | access to local variable i | E.cs:411:9:411:9 | access to local variable i | null | true |
|
||||
| E.cs:422:13:422:22 | access to property HasValue | E.cs:422:13:422:13 | access to parameter i | false | true |
|
||||
| E.cs:422:13:422:22 | access to property HasValue | E.cs:422:13:422:13 | access to parameter i | true | false |
|
||||
| E.cs:429:13:429:22 | access to property HasValue | E.cs:429:13:429:13 | access to parameter i | false | true |
|
||||
| E.cs:429:13:429:22 | access to property HasValue | E.cs:429:13:429:13 | access to parameter i | true | false |
|
||||
| Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | Forwarding.cs:9:14:9:14 | access to local variable s | false | false |
|
||||
| Forwarding.cs:14:13:14:32 | call to method IsNotNullOrEmpty | Forwarding.cs:14:13:14:13 | access to local variable s | true | false |
|
||||
| Forwarding.cs:19:14:19:23 | call to method IsNull | Forwarding.cs:19:14:19:14 | access to local variable s | false | false |
|
||||
|
||||
@@ -406,8 +406,6 @@ nodes
|
||||
| E.cs:404:9:404:18 | SSA def(i) |
|
||||
| E.cs:404:9:404:18 | SSA def(i) |
|
||||
| E.cs:405:16:405:16 | access to local variable i |
|
||||
| E.cs:417:24:417:40 | SSA capture def(i) |
|
||||
| E.cs:417:34:417:34 | access to parameter i |
|
||||
| Forwarding.cs:7:16:7:23 | SSA def(s) |
|
||||
| Forwarding.cs:9:13:9:30 | [false] !... |
|
||||
| Forwarding.cs:14:9:17:9 | if (...) ... |
|
||||
@@ -797,7 +795,6 @@ edges
|
||||
| E.cs:384:27:384:28 | access to parameter e2 | E.cs:384:13:384:36 | [false] ... && ... |
|
||||
| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
|
||||
| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
|
||||
| E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i |
|
||||
| Forwarding.cs:7:16:7:23 | SSA def(s) | Forwarding.cs:9:13:9:30 | [false] !... |
|
||||
| Forwarding.cs:9:13:9:30 | [false] !... | Forwarding.cs:14:9:17:9 | if (...) ... |
|
||||
| Forwarding.cs:14:9:17:9 | if (...) ... | Forwarding.cs:19:9:22:9 | if (...) ... |
|
||||
@@ -910,7 +907,6 @@ edges
|
||||
| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null here as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:28:382:37 | ... != ... | this |
|
||||
| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null here as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:58:382:67 | ... == ... | this |
|
||||
| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null here as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:384:27:384:36 | ... == ... | this |
|
||||
| E.cs:417:34:417:34 | access to parameter i | E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:415:27:415:27 | i | i | E.cs:415:27:415:27 | i | this |
|
||||
| GuardedString.cs:35:31:35:31 | access to local variable s | GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null here because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this |
|
||||
| NullMaybeBad.cs:7:27:7:27 | access to parameter o | NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null here because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this |
|
||||
| StringConcatenation.cs:16:17:16:17 | access to local variable s | StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this |
|
||||
|
||||
@@ -52,6 +52,11 @@ The following properties are supported by all query files:
|
||||
| ``@security-severity``| ``<score>`` | Defines the level of severity, between 0.0 and 10.0, for queries with ``@tags security``. For more information about calculating ``@security-severity``, see the `GitHub changelog <https://github.blog/changelog/2021-07-19-codeql-code-scanning-new-severity-levels-for-security-alerts/>`__. |
|
||||
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Additional properties for filter queries
|
||||
----------------------------------------
|
||||
|
||||
Filter queries are used to define additional constraints to limit the results that are returned by other queries. A filter query must have the same ``@kind`` property as the query whose results it is filtering. No additional metadata properties are required.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.0.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
1
java/ql/lib/change-notes/released/0.0.9.md
Normal file
1
java/ql/lib/change-notes/released/0.0.9.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.9
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-all
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
|
||||
@@ -1,648 +0,0 @@
|
||||
/*
|
||||
* External artifacts
|
||||
*/
|
||||
|
||||
externalDefects(
|
||||
unique int id : @externalDefect,
|
||||
varchar(900) queryPath : string ref,
|
||||
int location : @location ref,
|
||||
varchar(900) message : string ref,
|
||||
float severity : float ref
|
||||
);
|
||||
|
||||
externalMetrics(
|
||||
unique int id : @externalMetric,
|
||||
varchar(900) queryPath : string ref,
|
||||
int location : @location ref,
|
||||
float value : float ref
|
||||
);
|
||||
|
||||
externalData(
|
||||
int id : @externalDataElement,
|
||||
varchar(900) path : string ref,
|
||||
int column: int ref,
|
||||
varchar(900) value : string ref
|
||||
);
|
||||
|
||||
snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
/*
|
||||
* Duplicate code
|
||||
*/
|
||||
|
||||
duplicateCode(
|
||||
unique int id : @duplication,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
similarCode(
|
||||
unique int id : @similarity,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
@duplication_or_similarity = @duplication | @similarity
|
||||
|
||||
tokens(
|
||||
int id : @duplication_or_similarity ref,
|
||||
int offset : int ref,
|
||||
int beginLine : int ref,
|
||||
int beginColumn : int ref,
|
||||
int endLine : int ref,
|
||||
int endColumn : int ref);
|
||||
|
||||
/*
|
||||
* Version history
|
||||
*/
|
||||
|
||||
svnentries(
|
||||
int id : @svnentry,
|
||||
varchar(500) revision : string ref,
|
||||
varchar(500) author : string ref,
|
||||
date revisionDate : date ref,
|
||||
int changeSize : int ref
|
||||
)
|
||||
|
||||
svnaffectedfiles(
|
||||
int id : @svnentry ref,
|
||||
int file : @file ref,
|
||||
varchar(500) action : string ref
|
||||
)
|
||||
|
||||
svnentrymsg(
|
||||
int id : @svnentry ref,
|
||||
varchar(500) message : string ref
|
||||
)
|
||||
|
||||
svnchurn(
|
||||
int commit : @svnentry ref,
|
||||
int file : @file ref,
|
||||
int churnedLines : int ref
|
||||
)
|
||||
|
||||
/*
|
||||
* Java dbscheme
|
||||
*/
|
||||
|
||||
@location = @location_default ;
|
||||
|
||||
locations_default(unique int id: @location_default,
|
||||
int file: @file ref,
|
||||
int beginLine: int ref,
|
||||
int beginColumn: int ref,
|
||||
int endLine: int ref,
|
||||
int endColumn: int ref
|
||||
);
|
||||
|
||||
hasLocation(int locatableid: @locatable ref, int id: @location ref);
|
||||
|
||||
@sourceline = @locatable ;
|
||||
|
||||
numlines(int element_id: @sourceline ref,
|
||||
int num_lines: int ref,
|
||||
int num_code: int ref,
|
||||
int num_comment: int ref
|
||||
);
|
||||
|
||||
/*
|
||||
fromSource(0) = unknown,
|
||||
fromSource(1) = from source,
|
||||
fromSource(2) = from library
|
||||
*/
|
||||
files(unique int id: @file,
|
||||
varchar(900) name: string ref,
|
||||
varchar(900) simple: string ref,
|
||||
varchar(900) ext: string ref,
|
||||
int fromSource: int ref);
|
||||
|
||||
folders(unique int id: @folder,
|
||||
varchar(900) name: string ref,
|
||||
varchar(900) simple: string ref);
|
||||
|
||||
@container = @folder | @file
|
||||
|
||||
containerparent(int parent: @container ref,
|
||||
unique int child: @container ref);
|
||||
|
||||
cupackage (unique int id: @file ref, int packageid: @package ref);
|
||||
|
||||
/* Java */
|
||||
|
||||
packages (unique int id: @package,
|
||||
varchar(900) nodeName: string ref);
|
||||
|
||||
primitives (unique int id: @primitive,
|
||||
varchar(20) nodeName: string ref);
|
||||
|
||||
modifiers (unique int id: @modifier,
|
||||
varchar(20) nodeName: string ref);
|
||||
|
||||
classes (unique int id: @class,
|
||||
varchar(900) nodeName: string ref,
|
||||
int parentid: @package ref,
|
||||
int sourceid: @class ref);
|
||||
|
||||
interfaces (unique int id: @interface,
|
||||
varchar(900) nodeName: string ref,
|
||||
int parentid: @package ref,
|
||||
int sourceid: @interface ref);
|
||||
|
||||
fielddecls (unique int id: @fielddecl,
|
||||
int parentid: @reftype ref);
|
||||
|
||||
fieldDeclaredIn (int fieldId: @field ref,
|
||||
int fieldDeclId: @fielddecl ref,
|
||||
int pos: int ref);
|
||||
|
||||
fields (unique int id: @field,
|
||||
varchar(900) nodeName: string ref,
|
||||
int typeid: @type ref,
|
||||
int parentid: @reftype ref,
|
||||
int sourceid: @field ref);
|
||||
|
||||
constrs (unique int id: @constructor,
|
||||
varchar(900) nodeName: string ref,
|
||||
varchar(900) signature: string ref,
|
||||
int typeid: @type ref,
|
||||
int parentid: @reftype ref,
|
||||
int sourceid: @constructor ref);
|
||||
|
||||
methods (unique int id: @method,
|
||||
varchar(900) nodeName: string ref,
|
||||
varchar(900) signature: string ref,
|
||||
int typeid: @type ref,
|
||||
int parentid: @reftype ref,
|
||||
int sourceid: @method ref);
|
||||
|
||||
params (int id: @param,
|
||||
varchar(900) nodeName: string ref,
|
||||
int typeid: @type ref,
|
||||
int pos: int ref,
|
||||
int parentid: @callable ref,
|
||||
int sourceid: @param ref);
|
||||
|
||||
exceptions (unique int id: @exception,
|
||||
int typeid: @type ref,
|
||||
int parentid: @callable ref);
|
||||
|
||||
isAnnotType (int interfaceid: @interface ref);
|
||||
|
||||
isAnnotElem (int methodid: @method ref);
|
||||
|
||||
// annotValue(annot, id2, value) holds iff
|
||||
// annot is an application of an annotation @A(v1=n1,...,vk=nk)]
|
||||
// && id2=vi, value=ni for some i
|
||||
annotValue (int parentid: @annotation ref,
|
||||
int id2: @method ref,
|
||||
unique int value: @expr ref); // unique because source/bytecode expressions are disjoint
|
||||
|
||||
isEnumType (int classid: @class ref);
|
||||
|
||||
isEnumConst (int fieldid: @field ref);
|
||||
|
||||
typeVars (unique int id: @typevariable,
|
||||
varchar(900) nodeName: string ref,
|
||||
int pos: int ref,
|
||||
int kind: int ref, // unused, but kept for backwards compatibility
|
||||
int parentid: @typeormethod ref);
|
||||
|
||||
wildcards (unique int id: @wildcard,
|
||||
varchar(900) nodeName: string ref,
|
||||
int kind: int ref);
|
||||
|
||||
typeBounds (unique int id: @typebound,
|
||||
int typeid: @reftype ref, // reftype because there are no primitive bounds
|
||||
int pos: int ref,
|
||||
int parentid: @boundedtype ref);
|
||||
|
||||
typeArgs (int argumentid: @reftype ref,
|
||||
int pos: int ref,
|
||||
int parentid: @typeormethod ref);
|
||||
|
||||
isParameterized(int memberid: @member ref);
|
||||
|
||||
isRaw (int memberid: @member ref);
|
||||
|
||||
erasure (unique int memberid: @member ref,
|
||||
int erasureid: @member ref);
|
||||
|
||||
isAnonymClass (int classid: @class ref,
|
||||
int parent: @classinstancexpr ref);
|
||||
|
||||
isLocalClass (int classid: @class ref,
|
||||
int parent: @localclassdeclstmt ref);
|
||||
|
||||
isDefConstr (int constructorid: @constructor ref);
|
||||
|
||||
arrays (unique int id: @array,
|
||||
varchar(900) nodeName: string ref,
|
||||
int elementtypeid: @type ref,
|
||||
int dimension: int ref,
|
||||
int componenttypeid: @type ref);
|
||||
|
||||
enclInReftype (unique int child: @reftype ref,
|
||||
int parent: @reftype ref);
|
||||
|
||||
// id1 extends id2
|
||||
extendsReftype (int id1: @reftype ref,
|
||||
int id2: @classorinterface ref);
|
||||
|
||||
implInterface (int id1: @classorarray ref,
|
||||
int id2: @interface ref);
|
||||
|
||||
hasModifier (int id1: @modifiable ref,
|
||||
int id2: @modifier ref);
|
||||
|
||||
readsField (unique int id: @readsFieldExpr,
|
||||
int id1: @callable ref,
|
||||
int id2: @field ref);
|
||||
|
||||
writesField (unique int id: @writesFieldExpr,
|
||||
int id1: @callable ref,
|
||||
int id2: @field ref);
|
||||
|
||||
callsMethod (unique int id: @makesMethodCallExpr,
|
||||
int id1: @callable ref,
|
||||
int id2: @method ref,
|
||||
int kind: int ref);
|
||||
|
||||
callsConstr (unique int id: @makesConstructorCallExpr,
|
||||
int id1: @callable ref,
|
||||
int id2: @constructor ref,
|
||||
int kind: int ref);
|
||||
|
||||
imports (unique int id: @import,
|
||||
int holder: @typeorpackage ref,
|
||||
varchar(900) name: string ref,
|
||||
int kind: int ref);
|
||||
|
||||
stmts (unique int id: @stmt,
|
||||
int kind: int ref,
|
||||
int parent: @stmtparent ref,
|
||||
int idx: int ref,
|
||||
int bodydecl: @callable ref);
|
||||
|
||||
@stmtparent = @callable | @stmt;
|
||||
|
||||
succs(int fromSuccessor: @stmt ref,
|
||||
int toSuccessor: @stmtparent ref);
|
||||
|
||||
case @stmt.kind of
|
||||
0 = @block
|
||||
| 1 = @ifstmt
|
||||
| 2 = @forstmt
|
||||
| 3 = @enhancedforstmt
|
||||
| 4 = @whilestmt
|
||||
| 5 = @dostmt
|
||||
| 6 = @trystmt
|
||||
| 7 = @switchstmt
|
||||
| 8 = @synchronizedstmt
|
||||
| 9 = @returnstmt
|
||||
| 10 = @throwstmt
|
||||
| 11 = @breakstmt
|
||||
| 12 = @continuestmt
|
||||
| 13 = @emptystmt
|
||||
| 14 = @exprstmt
|
||||
| 15 = @labeledstmt
|
||||
| 16 = @assertstmt
|
||||
| 17 = @localvariabledeclstmt
|
||||
| 18 = @localclassdeclstmt
|
||||
| 19 = @constructorinvocationstmt
|
||||
| 20 = @superconstructorinvocationstmt
|
||||
| 21 = @case
|
||||
| 22 = @catchclause;
|
||||
|
||||
exprs(
|
||||
unique int id: @expr,
|
||||
int kind: int ref,
|
||||
int typeid: @type ref,
|
||||
int parent: @element ref, // to deal with annotations inside annotations
|
||||
int idx: int ref
|
||||
);
|
||||
|
||||
callableEnclosingExpr(
|
||||
unique int id: @expr ref,
|
||||
int callable_id: @callable ref
|
||||
);
|
||||
|
||||
statementEnclosingExpr(
|
||||
unique int id: @expr ref,
|
||||
int statement_id: @stmt ref
|
||||
);
|
||||
|
||||
case @expr.kind of
|
||||
1 = @arrayaccess
|
||||
| 2 = @arraycreationexpr
|
||||
| 3 = @arrayinit
|
||||
| 4 = @assignexpr
|
||||
| 5 = @assignaddexpr
|
||||
| 6 = @assignsubexpr
|
||||
| 7 = @assignmulexpr
|
||||
| 8 = @assigndivexpr
|
||||
| 9 = @assignremexpr
|
||||
| 10 = @assignandexpr
|
||||
| 11 = @assignorexpr
|
||||
| 12 = @assignxorexpr
|
||||
| 13 = @assignlshiftexpr
|
||||
| 14 = @assignrshiftexpr
|
||||
| 15 = @assignurshiftexpr
|
||||
| 16 = @booleanliteral
|
||||
| 17 = @integerliteral
|
||||
| 18 = @longliteral
|
||||
| 19 = @floatingpointliteral
|
||||
| 20 = @doubleliteral
|
||||
| 21 = @characterliteral
|
||||
| 22 = @stringliteral
|
||||
| 23 = @nullliteral
|
||||
| 24 = @mulexpr
|
||||
| 25 = @divexpr
|
||||
| 26 = @remexpr
|
||||
| 27 = @addexpr
|
||||
| 28 = @subexpr
|
||||
| 29 = @lshiftexpr
|
||||
| 30 = @rshiftexpr
|
||||
| 31 = @urshiftexpr
|
||||
| 32 = @andbitexpr
|
||||
| 33 = @orbitexpr
|
||||
| 34 = @xorbitexpr
|
||||
| 35 = @andlogicalexpr
|
||||
| 36 = @orlogicalexpr
|
||||
| 37 = @ltexpr
|
||||
| 38 = @gtexpr
|
||||
| 39 = @leexpr
|
||||
| 40 = @geexpr
|
||||
| 41 = @eqexpr
|
||||
| 42 = @neexpr
|
||||
| 43 = @postincexpr
|
||||
| 44 = @postdecexpr
|
||||
| 45 = @preincexpr
|
||||
| 46 = @predecexpr
|
||||
| 47 = @minusexpr
|
||||
| 48 = @plusexpr
|
||||
| 49 = @bitnotexpr
|
||||
| 50 = @lognotexpr
|
||||
| 51 = @castexpr
|
||||
| 52 = @classinstancexpr
|
||||
| 53 = @conditionalexpr
|
||||
| 54 = @parexpr
|
||||
| 55 = @instanceofexpr
|
||||
| 56 = @localvariabledeclexpr
|
||||
| 57 = @typeliteral
|
||||
| 58 = @thisaccess
|
||||
| 59 = @superaccess
|
||||
| 60 = @varaccess
|
||||
| 61 = @methodaccess
|
||||
| 62 = @typeaccess
|
||||
| 63 = @arraytypeaccess
|
||||
| 64 = @packageaccess
|
||||
| 65 = @wildcardtypeaccess
|
||||
| 66 = @annotation
|
||||
| 67 = @uniontypeaccess;
|
||||
|
||||
|
||||
@assignment = @assignexpr
|
||||
| @assignop;
|
||||
|
||||
@unaryassignment = @postincexpr
|
||||
| @postdecexpr
|
||||
| @preincexpr
|
||||
| @predecexpr;
|
||||
|
||||
@assignop = @assignaddexpr
|
||||
| @assignsubexpr
|
||||
| @assignmulexpr
|
||||
| @assigndivexpr
|
||||
| @assignremexpr
|
||||
| @assignandexpr
|
||||
| @assignorexpr
|
||||
| @assignxorexpr
|
||||
| @assignlshiftexpr
|
||||
| @assignrshiftexpr
|
||||
| @assignurshiftexpr;
|
||||
|
||||
@literal = @booleanliteral
|
||||
| @integerliteral
|
||||
| @longliteral
|
||||
| @floatingpointliteral
|
||||
| @doubleliteral
|
||||
| @characterliteral
|
||||
| @stringliteral
|
||||
| @nullliteral;
|
||||
|
||||
@binaryexpr = @mulexpr
|
||||
| @divexpr
|
||||
| @remexpr
|
||||
| @addexpr
|
||||
| @subexpr
|
||||
| @lshiftexpr
|
||||
| @rshiftexpr
|
||||
| @urshiftexpr
|
||||
| @andbitexpr
|
||||
| @orbitexpr
|
||||
| @xorbitexpr
|
||||
| @andlogicalexpr
|
||||
| @orlogicalexpr
|
||||
| @ltexpr
|
||||
| @gtexpr
|
||||
| @leexpr
|
||||
| @geexpr
|
||||
| @eqexpr
|
||||
| @neexpr;
|
||||
|
||||
@unaryexpr = @postincexpr
|
||||
| @postdecexpr
|
||||
| @preincexpr
|
||||
| @predecexpr
|
||||
| @minusexpr
|
||||
| @plusexpr
|
||||
| @bitnotexpr
|
||||
| @lognotexpr;
|
||||
|
||||
@caller = @classinstancexpr
|
||||
| @methodaccess
|
||||
| @constructorinvocationstmt
|
||||
| @superconstructorinvocationstmt;
|
||||
|
||||
@abscaller = @caller | @callExpr ;
|
||||
|
||||
callableBinding (unique int callerid: @caller ref,
|
||||
int callee: @callable ref);
|
||||
|
||||
@exprparent = @stmt | @expr | @callable | @field | @fielddecl | @class | @interface;
|
||||
|
||||
variableBinding (unique int expr: @varaccess ref,
|
||||
int variable: @variable ref);
|
||||
|
||||
@variable = @localvar | @param | @field;
|
||||
@localorparam = @localvar | @param;
|
||||
|
||||
localvars (unique int id: @localvar,
|
||||
varchar(900) nodeName: string ref,
|
||||
int typeid: @type ref,
|
||||
int parentid: @localvariabledeclexpr ref);
|
||||
|
||||
@namedexprorstmt =
|
||||
@breakstmt
|
||||
| @continuestmt
|
||||
| @labeledstmt
|
||||
| @literal;
|
||||
|
||||
namestrings (varchar(900) name: string ref,
|
||||
unique int parent: @namedexprorstmt ref);
|
||||
|
||||
javadoc (unique int id: @javadoc);
|
||||
|
||||
isNormalComment(int commentid : @javadoc ref);
|
||||
|
||||
hasJavadoc (int documentableid: @member ref,
|
||||
int javadocid: @javadoc ref);
|
||||
|
||||
javadocTag (unique int id: @javadocTag,
|
||||
varchar(900) name: string ref,
|
||||
int parentid: @javadocParent ref,
|
||||
int idx: int ref);
|
||||
|
||||
javadocText (unique int id: @javadocText,
|
||||
varchar(900) text: string ref,
|
||||
int parentid: @javadocParent ref,
|
||||
int idx: int ref);
|
||||
|
||||
@typeorpackage = @type | @package;
|
||||
|
||||
@child = @typeorpackage | @typeormethod | @callable;
|
||||
|
||||
@modifiable_or_locatable = @modifiable | @locatable_element;
|
||||
|
||||
@named_element = @commentable | @modifier_named;
|
||||
|
||||
@typeormethod = @type | @method;
|
||||
@classorinterface = @interface | @class;
|
||||
@boundedtype = @typevariable | @wildcard;
|
||||
@reftype = @classorinterface | @array | @boundedtype;
|
||||
@classorarray = @class | @array;
|
||||
@type = @primitive | @reftype;
|
||||
@callable = @method | @constructor;
|
||||
@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field |
|
||||
@annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl;
|
||||
|
||||
@modifiable = @member_modifiable| @param | @localvar ;
|
||||
|
||||
@commentable = @package | @modifiable | @locatable_element ;
|
||||
|
||||
@package_member = @file | @param | @member ;
|
||||
|
||||
@member_modifiable = @class | @interface | @method | @constructor | @field ;
|
||||
|
||||
@expression = @callExpr | @fieldAccessExpr;
|
||||
@fieldAccessExpr = @readsFieldExpr | @writesFieldExpr;
|
||||
@callExpr = @makesMethodCallExpr | @makesConstructorCallExpr;
|
||||
|
||||
@member = @method | @constructor | @field | @reftype ;
|
||||
|
||||
@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception
|
||||
| @boundedtype | @typebound | @array
|
||||
| @readsFieldExpr | @writesFieldExpr | @makesMethodCallExpr | @makesConstructorCallExpr
|
||||
| @import | @stmt | @expr | @localvar | @javadoc | @javadocTag | @javadocText
|
||||
| @xmllocatable | @externalDefect | @externalMetric;
|
||||
|
||||
@locatable_element = @file | @class | @interface | @field | @param | @exception | @callable
|
||||
|
||||
@named = @param | @member | @package | @typeormethod | @file;
|
||||
|
||||
@modifier_named = @modifier | @modifiable | @named;
|
||||
|
||||
@javadocParent = @javadoc | @javadocTag;
|
||||
@javadocElement = @javadocTag | @javadocText;
|
||||
|
||||
/* XML Files */
|
||||
|
||||
xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref);
|
||||
|
||||
xmlDTDs (unique int id: @xmldtd,
|
||||
varchar(900) root: string ref,
|
||||
varchar(900) publicId: string ref,
|
||||
varchar(900) systemId: string ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlElements (unique int id: @xmlelement,
|
||||
varchar(900) name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlAttrs (unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
varchar(900) name: string ref,
|
||||
varchar(3600) value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlNs (int id: @xmlnamespace,
|
||||
varchar(900) prefixName: string ref,
|
||||
varchar(900) URI: string ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlHasNs (int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlComments (unique int id: @xmlcomment,
|
||||
varchar(3600) text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
xmlChars (unique int id: @xmlcharacters,
|
||||
varchar(3600) text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
@top = @element | @locatable | @folder;
|
||||
|
||||
/* *** Well-Founded Orders *** */
|
||||
|
||||
/* The type hierarchy order */
|
||||
order:typeOrder(3);
|
||||
|
||||
key:extendsReftype.order(id1, id2, typeOrder);
|
||||
key:implInterface.order(id1, id2, typeOrder);
|
||||
|
||||
/* The AST parent-child order */
|
||||
|
||||
order:astChildOrder(4);
|
||||
|
||||
key:classes.order(id, parentid, astChildOrder); // Transitive
|
||||
key:interfaces.order(id, parentid, astChildOrder); // Transitive
|
||||
key:fields.order(id, parentid, astChildOrder);
|
||||
key:methods.order(id, parentid, astChildOrder);
|
||||
key:constrs.order(id, parentid, astChildOrder);
|
||||
key:params.order(id, parentid, astChildOrder);
|
||||
key:exceptions.order(id, parentid, astChildOrder);
|
||||
key:typeVars.order(id, parentid, astChildOrder);
|
||||
key:typeBounds.order(id, parentid, astChildOrder);
|
||||
key:stmts.order(id,parent,astChildOrder);
|
||||
key:stmts.order(id,bodydecl,astChildOrder);
|
||||
key:exprs.order(id,parent,astChildOrder);
|
||||
key:localvars.order(id,parentid,astChildOrder);
|
||||
|
||||
/* Calls and field accesses */
|
||||
|
||||
key:readsField.order(id, id1, astChildOrder);
|
||||
key:writesField.order(id, id1, astChildOrder);
|
||||
key:callsMethod.order(id, id1, astChildOrder);
|
||||
key:callsConstr.order(id, id1, astChildOrder);
|
||||
|
||||
/* Binary Relations */
|
||||
|
||||
key:enclInReftype.order(child, parent, astChildOrder);
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.0.9
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query "Cleartext storage of sensitive information using a local database on Android" (`java/android/cleartext-storage-database`) has been added. This query finds instances of sensitive data being stored in local databases without encryption, which may expose it to attackers or malicious applications.
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### New Queries
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
## 0.0.9
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query "Cleartext storage of sensitive information using a local database on Android" (`java/android/cleartext-storage-database`) has been added. This query finds instances of sensitive data being stored in local databases without encryption, which may expose it to attackers or malicious applications.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.8
|
||||
lastReleaseVersion: 0.0.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-queries
|
||||
version: 0.0.9-dev
|
||||
version: 0.0.9
|
||||
groups:
|
||||
- java
|
||||
- queries
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.0.10
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
1
javascript/ql/lib/change-notes/released/0.0.10.md
Normal file
1
javascript/ql/lib/change-notes/released/0.0.10.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.10
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.9
|
||||
lastReleaseVersion: 0.0.10
|
||||
|
||||
@@ -122,7 +122,6 @@ import semmle.javascript.frameworks.Request
|
||||
import semmle.javascript.frameworks.RxJS
|
||||
import semmle.javascript.frameworks.ServerLess
|
||||
import semmle.javascript.frameworks.ShellJS
|
||||
import semmle.javascript.frameworks.Snapdragon
|
||||
import semmle.javascript.frameworks.SystemCommandExecutors
|
||||
import semmle.javascript.frameworks.SQL
|
||||
import semmle.javascript.frameworks.SocketIO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-all
|
||||
version: 0.0.10-dev
|
||||
version: 0.0.10
|
||||
groups: javascript
|
||||
dbscheme: semmlecode.javascript.dbscheme
|
||||
extractor: javascript
|
||||
|
||||
@@ -1166,36 +1166,6 @@ module TaintTracking {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `guard` is a test that checks if `operand` is a number. */
|
||||
predicate isNumberGuard(DataFlow::Node guard, Expr operand, boolean polarity) {
|
||||
exists(DataFlow::CallNode isNaN |
|
||||
isNaN = DataFlow::globalVarRef("isNaN").getACall() and guard = isNaN and polarity = false
|
||||
|
|
||||
operand = isNaN.getArgument(0).asExpr()
|
||||
or
|
||||
exists(DataFlow::CallNode parse |
|
||||
parse = DataFlow::globalVarRef(["parseInt", "parseFloat"]).getACall()
|
||||
|
|
||||
parse = isNaN.getArgument(0) and
|
||||
operand = parse.getArgument(0).asExpr()
|
||||
)
|
||||
or
|
||||
exists(UnaryExpr unary | unary.getOperator() = ["+", "-"] |
|
||||
unary = isNaN.getArgument(0).asExpr() and
|
||||
operand = unary.getOperand()
|
||||
)
|
||||
or
|
||||
exists(BinaryExpr bin | bin.getOperator() = ["+", "-"] |
|
||||
bin = isNaN.getArgument(0).asExpr() and
|
||||
operand = bin.getAnOperand() and
|
||||
bin.getAnOperand() instanceof NumberLiteral
|
||||
)
|
||||
)
|
||||
or
|
||||
isTypeofGuard(guard.asExpr(), operand, "number") and
|
||||
polarity = guard.asExpr().(EqualityTest).getPolarity()
|
||||
}
|
||||
|
||||
/** DEPRECATED. This class has been renamed to `MembershipTestSanitizer`. */
|
||||
deprecated class StringInclusionSanitizer = MembershipTestSanitizer;
|
||||
|
||||
|
||||
@@ -6,15 +6,27 @@ import javascript
|
||||
private import semmle.javascript.security.dataflow.Xss as Xss
|
||||
|
||||
module Cheerio {
|
||||
/** A reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
private API::Node cheerioApi() {
|
||||
result = API::moduleImport("cheerio")
|
||||
/**
|
||||
* A reference to the `cheerio` function, possibly with a loaded DOM.
|
||||
*/
|
||||
private DataFlow::SourceNode cheerioRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
(
|
||||
result = DataFlow::moduleImport("cheerio")
|
||||
or
|
||||
exists(string name | result = cheerioRef().getAMemberCall(name) |
|
||||
name = "load" or
|
||||
name = "parseHTML"
|
||||
)
|
||||
)
|
||||
or
|
||||
result = cheerioApi().getMember(["load", "parseHTML"]).getReturn()
|
||||
exists(DataFlow::TypeTracker t2 | result = cheerioRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** A reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
DataFlow::SourceNode cheerioRef() { result = cheerioApi().getAUse() }
|
||||
/**
|
||||
* A reference to the `cheerio` function, possibly with a loaded DOM.
|
||||
*/
|
||||
DataFlow::SourceNode cheerioRef() { result = cheerioRef(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/**
|
||||
* A creation of `cheerio` object, a collection of virtual DOM elements
|
||||
@@ -31,9 +43,9 @@ module Cheerio {
|
||||
|
||||
private class DefaultRange extends Range {
|
||||
DefaultRange() {
|
||||
this = cheerioApi().getACall()
|
||||
this = cheerioRef().getACall()
|
||||
or
|
||||
this = cheerioApi().getAMember().getACall()
|
||||
this = cheerioRef().getAMethodCall()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,11 +463,16 @@ module ClientRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instantiation `socket` of `require("net").Socket`.
|
||||
* Gets an instantiation `socket` of `require("net").Socket` type tracked using `t`.
|
||||
*/
|
||||
private API::Node netSocketInstantiation(DataFlow::NewNode socket) {
|
||||
result = API::moduleImport("net").getMember("Socket").getInstance() and
|
||||
socket = result.getAnImmediateUse()
|
||||
private DataFlow::SourceNode netSocketInstantiation(
|
||||
DataFlow::TypeTracker t, DataFlow::NewNode socket
|
||||
) {
|
||||
t.start() and
|
||||
socket = DataFlow::moduleMember("net", "Socket").getAnInstantiation() and
|
||||
result = socket
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = netSocketInstantiation(t2, socket).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,7 +481,9 @@ module ClientRequest {
|
||||
class NetSocketRequest extends ClientRequest::Range {
|
||||
DataFlow::NewNode socket;
|
||||
|
||||
NetSocketRequest() { this = netSocketInstantiation(socket).getMember("connect").getACall() }
|
||||
NetSocketRequest() {
|
||||
this = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMethodCall("connect")
|
||||
}
|
||||
|
||||
override DataFlow::Node getUrl() {
|
||||
result = this.getArgument([0, 1]) // there are multiple overrides of `connect`, and the URL can be in the first or second argument.
|
||||
@@ -488,7 +495,7 @@ module ClientRequest {
|
||||
responseType = "text" and
|
||||
promise = false and
|
||||
exists(DataFlow::CallNode call |
|
||||
call = netSocketInstantiation(socket).getMember("on").getACall() and
|
||||
call = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMemberCall("on") and
|
||||
call.getArgument(0).mayHaveStringValue("data") and
|
||||
result = call.getABoundCallbackParameter(1, 0)
|
||||
)
|
||||
@@ -496,7 +503,7 @@ module ClientRequest {
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
exists(DataFlow::CallNode call |
|
||||
call = netSocketInstantiation(socket).getMember("write").getACall() and
|
||||
call = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMemberCall("write") and
|
||||
result = call.getArgument(0)
|
||||
)
|
||||
}
|
||||
@@ -706,15 +713,22 @@ module ClientRequest {
|
||||
* Gets a reference to an instance of `chrome-remote-interface`.
|
||||
*
|
||||
* An instantiation of `chrome-remote-interface` either accepts a callback or returns a promise.
|
||||
*
|
||||
* The `isPromise` parameter reflects whether the reference is a promise containing
|
||||
* an instance of `chrome-remote-interface`, or an instance of `chrome-remote-interface`.
|
||||
*/
|
||||
private API::Node chromeRemoteInterface() {
|
||||
exists(API::CallNode call | call = API::moduleImport("chrome-remote-interface").getACall() |
|
||||
private DataFlow::SourceNode chromeRemoteInterface(DataFlow::TypeTracker t) {
|
||||
exists(DataFlow::CallNode call |
|
||||
call = DataFlow::moduleImport("chrome-remote-interface").getAnInvocation()
|
||||
|
|
||||
// the client is inside in a promise.
|
||||
result = call.getReturn().getPromised()
|
||||
t.startInPromise() and result = call
|
||||
or
|
||||
// the client is accessed directly using a callback.
|
||||
result = call.getParameter([0 .. 1]).getParameter(0)
|
||||
t.start() and result = call.getCallback([0 .. 1]).getParameter(0)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = chromeRemoteInterface(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -724,12 +738,14 @@ module ClientRequest {
|
||||
int optionsArg;
|
||||
|
||||
ChromeRemoteInterfaceRequest() {
|
||||
exists(API::Node instance | instance = chromeRemoteInterface() |
|
||||
exists(DataFlow::SourceNode instance |
|
||||
instance = chromeRemoteInterface(DataFlow::TypeTracker::end())
|
||||
|
|
||||
optionsArg = 0 and
|
||||
this = instance.getMember("Page").getMember("navigate").getACall()
|
||||
this = instance.getAPropertyRead("Page").getAMemberCall("navigate")
|
||||
or
|
||||
optionsArg = 1 and
|
||||
this = instance.getMember("send").getACall() and
|
||||
this = instance.getAMemberCall("send") and
|
||||
this.getArgument(0).mayHaveStringValue("Page.navigate")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,13 +56,18 @@ module Electron {
|
||||
}
|
||||
}
|
||||
|
||||
private API::Node browserObject() { result.getAnImmediateUse() instanceof NewBrowserObject }
|
||||
private DataFlow::SourceNode browserObject(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result instanceof NewBrowserObject
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = browserObject(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node whose value may originate from a browser object instantiation.
|
||||
*/
|
||||
private class BrowserObjectByFlow extends BrowserObject {
|
||||
BrowserObjectByFlow() { browserObject().getAUse() = this }
|
||||
BrowserObjectByFlow() { browserObject(DataFlow::TypeTracker::end()).flowsTo(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,47 +76,72 @@ private class GlobFileNameSource extends FileNameSource {
|
||||
|
||||
/**
|
||||
* Gets a file name or an array of file names from the `globby` library.
|
||||
* The predicate uses type-tracking. However, type-tracking is only used to track a step out of a promise.
|
||||
*/
|
||||
private API::Node globbyFileNameSource() {
|
||||
// `require('globby').sync(_)`
|
||||
result = API::moduleImport("globby").getMember("sync").getReturn()
|
||||
private DataFlow::SourceNode globbyFileNameSource(DataFlow::TypeTracker t) {
|
||||
exists(string moduleName | moduleName = "globby" |
|
||||
// `require('globby').sync(_)`
|
||||
t.start() and
|
||||
result = DataFlow::moduleMember(moduleName, "sync").getACall()
|
||||
or
|
||||
// `files` in `require('globby')(_).then(files => ...)`
|
||||
t.startInPromise() and
|
||||
result = DataFlow::moduleImport(moduleName).getACall()
|
||||
)
|
||||
or
|
||||
// `files` in `require('globby')(_).then(files => ...)`
|
||||
result = API::moduleImport("globby").getReturn().getPromised()
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(globbyFileNameSource(t2), t, t2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name or an array of file names from the `globby` library.
|
||||
*/
|
||||
private class GlobbyFileNameSource extends FileNameSource {
|
||||
GlobbyFileNameSource() { this = globbyFileNameSource().getAnImmediateUse() }
|
||||
GlobbyFileNameSource() { this = globbyFileNameSource(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/** Gets a file name or an array of file names from the `fast-glob` library. */
|
||||
private API::Node fastGlobFileName() {
|
||||
// `require('fast-glob').sync(_)
|
||||
result = API::moduleImport("fast-glob").getMember("sync").getReturn()
|
||||
or
|
||||
exists(API::Node base |
|
||||
base = [API::moduleImport("fast-glob"), API::moduleImport("fast-glob").getMember("async")]
|
||||
|
|
||||
result = base.getReturn().getPromised()
|
||||
/**
|
||||
* Gets a file name or an array of file names from the `fast-glob` library.
|
||||
* The predicate uses type-tracking. However, type-tracking is only used to track a step out of a promise.
|
||||
*/
|
||||
private DataFlow::Node fastGlobFileNameSource(DataFlow::TypeTracker t) {
|
||||
exists(string moduleName | moduleName = "fast-glob" |
|
||||
// `require('fast-glob').sync(_)
|
||||
t.start() and result = DataFlow::moduleMember(moduleName, "sync").getACall()
|
||||
or
|
||||
exists(DataFlow::SourceNode f |
|
||||
f = DataFlow::moduleImport(moduleName)
|
||||
or
|
||||
f = DataFlow::moduleMember(moduleName, "async")
|
||||
|
|
||||
// `files` in `require('fast-glob')(_).then(files => ...)` and
|
||||
// `files` in `require('fast-glob').async(_).then(files => ...)`
|
||||
t.startInPromise() and result = f.getACall()
|
||||
)
|
||||
or
|
||||
// `file` in `require('fast-glob').stream(_).on(_, file => ...)`
|
||||
t.start() and
|
||||
result =
|
||||
DataFlow::moduleMember(moduleName, "stream")
|
||||
.getACall()
|
||||
.getAMethodCall(EventEmitter::on())
|
||||
.getCallback(1)
|
||||
.getParameter(0)
|
||||
)
|
||||
or
|
||||
result =
|
||||
API::moduleImport("fast-glob")
|
||||
.getMember("stream")
|
||||
.getReturn()
|
||||
.getMember(EventEmitter::on())
|
||||
.getParameter(1)
|
||||
.getParameter(0)
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(fastGlobFileNameSource(t2), t, t2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name or an array of file names from the `fast-glob` library.
|
||||
*/
|
||||
private class FastGlobFileNameSource extends FileNameSource {
|
||||
FastGlobFileNameSource() { this = fastGlobFileName().getAnImmediateUse() }
|
||||
FastGlobFileNameSource() { this = fastGlobFileNameSource(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,17 +220,24 @@ private class WriteFileAtomic extends FileSystemWriteAccess, DataFlow::CallNode
|
||||
/**
|
||||
* A call to the library `recursive-readdir`.
|
||||
*/
|
||||
private class RecursiveReadDir extends FileSystemAccess, FileNameProducer, API::CallNode {
|
||||
RecursiveReadDir() { this = API::moduleImport("recursive-readdir").getACall() }
|
||||
private class RecursiveReadDir extends FileSystemAccess, FileNameProducer, DataFlow::CallNode {
|
||||
RecursiveReadDir() { this = DataFlow::moduleImport("recursive-readdir").getACall() }
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getAFileName() { result = this.trackFileSource().getAnImmediateUse() }
|
||||
override DataFlow::Node getAFileName() {
|
||||
result = this.trackFileSource(DataFlow::TypeTracker::end())
|
||||
}
|
||||
|
||||
private API::Node trackFileSource() {
|
||||
result = this.getParameter([1 .. 2]).getParameter(1)
|
||||
private DataFlow::SourceNode trackFileSource(DataFlow::TypeTracker t) {
|
||||
t.start() and result = this.getCallback([1 .. 2]).getParameter(1)
|
||||
or
|
||||
not exists(this.getCallback([1 .. 2])) and result = this.getReturn().getPromised()
|
||||
t.startInPromise() and not exists(this.getCallback([1 .. 2])) and result = this
|
||||
or
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(this.trackFileSource(t2), t, t2)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,25 +248,33 @@ private module JSONFile {
|
||||
/**
|
||||
* A reader for JSON files.
|
||||
*/
|
||||
class JSONFileReader extends FileSystemReadAccess, API::CallNode {
|
||||
class JSONFileReader extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
JSONFileReader() {
|
||||
this = API::moduleImport("jsonfile").getMember(["readFile", "readFileSync"]).getACall()
|
||||
this =
|
||||
DataFlow::moduleMember("jsonfile", any(string s | s = "readFile" or s = "readFileSync"))
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getADataNode() { result = this.trackRead().getAnImmediateUse() }
|
||||
override DataFlow::Node getADataNode() { result = this.trackRead(DataFlow::TypeTracker::end()) }
|
||||
|
||||
private API::Node trackRead() {
|
||||
private DataFlow::SourceNode trackRead(DataFlow::TypeTracker t) {
|
||||
this.getCalleeName() = "readFile" and
|
||||
(
|
||||
result = this.getParameter([1 .. 2]).getParameter(1)
|
||||
t.start() and result = this.getCallback([1 .. 2]).getParameter(1)
|
||||
or
|
||||
not exists(this.getCallback([1 .. 2])) and result = this.getReturn().getPromised()
|
||||
t.startInPromise() and not exists(this.getCallback([1 .. 2])) and result = this
|
||||
)
|
||||
or
|
||||
t.start() and
|
||||
this.getCalleeName() = "readFileSync" and
|
||||
result = this.getReturn()
|
||||
result = this
|
||||
or
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(this.trackRead(t2), t, t2)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,21 +297,26 @@ private module JSONFile {
|
||||
/**
|
||||
* A call to the library `load-json-file`.
|
||||
*/
|
||||
private class LoadJsonFile extends FileSystemReadAccess, API::CallNode {
|
||||
private class LoadJsonFile extends FileSystemReadAccess, DataFlow::CallNode {
|
||||
LoadJsonFile() {
|
||||
this = API::moduleImport("load-json-file").getACall()
|
||||
this = DataFlow::moduleImport("load-json-file").getACall()
|
||||
or
|
||||
this = API::moduleImport("load-json-file").getMember("sync").getACall()
|
||||
this = DataFlow::moduleMember("load-json-file", "sync").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getADataNode() { result = this.trackRead().getAnImmediateUse() }
|
||||
override DataFlow::Node getADataNode() { result = this.trackRead(DataFlow::TypeTracker::end()) }
|
||||
|
||||
private API::Node trackRead() {
|
||||
this.getCalleeName() = "sync" and result = this.getReturn()
|
||||
private DataFlow::SourceNode trackRead(DataFlow::TypeTracker t) {
|
||||
this.getCalleeName() = "sync" and t.start() and result = this
|
||||
or
|
||||
not this.getCalleeName() = "sync" and result = this.getReturn().getPromised()
|
||||
not this.getCalleeName() = "sync" and t.startInPromise() and result = this
|
||||
or
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(this.trackRead(t2), t, t2)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,30 +338,38 @@ private class WriteJsonFile extends FileSystemWriteAccess, DataFlow::CallNode {
|
||||
/**
|
||||
* A call to the library `walkdir`.
|
||||
*/
|
||||
private class WalkDir extends FileNameProducer, FileSystemAccess, API::CallNode {
|
||||
private class WalkDir extends FileNameProducer, FileSystemAccess, DataFlow::CallNode {
|
||||
WalkDir() {
|
||||
this = API::moduleImport("walkdir").getACall()
|
||||
this = DataFlow::moduleImport("walkdir").getACall()
|
||||
or
|
||||
this = API::moduleImport("walkdir").getMember("sync").getACall()
|
||||
this = DataFlow::moduleMember("walkdir", "sync").getACall()
|
||||
or
|
||||
this = API::moduleImport("walkdir").getMember("async").getACall()
|
||||
this = DataFlow::moduleMember("walkdir", "async").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getAFileName() { result = this.trackFileSource().getAnImmediateUse() }
|
||||
override DataFlow::Node getAFileName() {
|
||||
result = this.trackFileSource(DataFlow::TypeTracker::end())
|
||||
}
|
||||
|
||||
private API::Node trackFileSource() {
|
||||
not this.getCalleeName() = ["sync", "async"] and
|
||||
private DataFlow::SourceNode trackFileSource(DataFlow::TypeTracker t) {
|
||||
not this.getCalleeName() = any(string s | s = "sync" or s = "async") and
|
||||
t.start() and
|
||||
(
|
||||
result = this.getParameter(this.getNumArgument() - 1).getParameter(0)
|
||||
result = this.getCallback(this.getNumArgument() - 1).getParameter(0)
|
||||
or
|
||||
result = this.getReturn().getMember(EventEmitter::on()).getParameter(1).getParameter(0)
|
||||
result = this.getAMethodCall(EventEmitter::on()).getCallback(1).getParameter(0)
|
||||
)
|
||||
or
|
||||
this.getCalleeName() = "sync" and result = this.getReturn()
|
||||
t.start() and this.getCalleeName() = "sync" and result = this
|
||||
or
|
||||
this.getCalleeName() = "async" and result = this.getReturn().getPromised()
|
||||
t.startInPromise() and this.getCalleeName() = "async" and result = this
|
||||
or
|
||||
// Tracking out of a promise
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = PromiseTypeTracking::promiseStep(this.trackFileSource(t2), t, t2)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Provides classes for working with applications using [snapdragon](https://www.npmjs.com/package/snapdragon).
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* A module modeling taint steps for the [snapdragon](https://www.npmjs.com/package/snapdragon) library.
|
||||
*/
|
||||
private module Snapdragon {
|
||||
private API::Node getSetCall(API::Node base) { result = base.getMember("set").getReturn() }
|
||||
|
||||
/**
|
||||
* A taint step through the [snapdragon](https://www.npmjs.com/package/snapdragon) library.
|
||||
*
|
||||
* Models both parsing (converting a string to an AST) and compilation (converting an AST to a string).
|
||||
* For example:
|
||||
* ```JavaScript
|
||||
* var snapdragon = new (require("snapdragon"))();
|
||||
* snapdragon.parser.set("foo", function () {
|
||||
* sink(this); // <- sink
|
||||
* });
|
||||
* snapdragon.parse("source", opts); // <- source
|
||||
* ```
|
||||
*/
|
||||
private class SnapDragonStep extends DataFlow::SharedFlowStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(string methodName, API::CallNode set, API::CallNode call, API::Node base |
|
||||
// the handler, registered with a call to `.set`.
|
||||
set = getSetCall+(base.getMember(methodName + "r")).getAnImmediateUse() and
|
||||
// the snapdragon instance. The API is chaining, you can also use the instance directly.
|
||||
base = API::moduleImport("snapdragon").getInstance() and
|
||||
methodName = ["parse", "compile"] and
|
||||
(
|
||||
// snapdragon.parse(..)
|
||||
call = getSetCall*(base).getMember(methodName).getACall()
|
||||
or
|
||||
// snapdragon.parser.set().set().parse(..)
|
||||
call = getSetCall*(set.getReturn()).getMember(methodName).getACall()
|
||||
)
|
||||
|
|
||||
pred = call.getArgument(0) and
|
||||
(
|
||||
// for parsers handlers the input is the `this` pointer.
|
||||
methodName = "parse" and
|
||||
succ = DataFlow::thisNode(set.getCallback(1).getFunction())
|
||||
or
|
||||
// for compiler handlers the input is the first parameter.
|
||||
methodName = "compile" and
|
||||
succ = set.getParameter(1).getParameter(0).getAnImmediateUse()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,11 @@ import javascript
|
||||
*/
|
||||
module SocketIO {
|
||||
/** Gets a data flow node that creates a new socket.io server. */
|
||||
private API::Node newServer() {
|
||||
result = API::moduleImport("socket.io").getReturn()
|
||||
private DataFlow::SourceNode newServer() {
|
||||
result = DataFlow::moduleImport("socket.io").getAnInvocation()
|
||||
or
|
||||
// alias for `Server`
|
||||
result = API::moduleImport("socket.io").getMember("listen").getReturn()
|
||||
result = DataFlow::moduleImport("socket.io").getAMemberCall("listen")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,12 +39,7 @@ module SocketIO {
|
||||
|
||||
/** A socket.io server. */
|
||||
class ServerObject extends SocketIOObject {
|
||||
API::Node node;
|
||||
|
||||
ServerObject() { node = newServer() and this = node.getAnImmediateUse() }
|
||||
|
||||
/** Gets the Api node for this server. */
|
||||
API::Node asApiNode() { result = node }
|
||||
ServerObject() { this = newServer() }
|
||||
|
||||
/** Gets the default namespace of this server. */
|
||||
NamespaceObject getDefaultNamespace() { result = MkNamespace(this, "/") }
|
||||
@@ -55,13 +50,17 @@ module SocketIO {
|
||||
/** Gets the namespace with the given path of this server. */
|
||||
NamespaceObject getNamespace(string path) { result = MkNamespace(this, path) }
|
||||
|
||||
/** Gets a api node that may refer to the socket.io server created at `srv`. */
|
||||
private API::Node server() {
|
||||
result = node
|
||||
/**
|
||||
* Gets a data flow node that may refer to the socket.io server created at `srv`.
|
||||
*/
|
||||
private DataFlow::SourceNode server(DataFlow::TypeTracker t) {
|
||||
result = this and t.start()
|
||||
or
|
||||
exists(API::Node pred | pred = server() |
|
||||
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode pred | pred = this.server(t2) |
|
||||
result = pred.track(t2, t)
|
||||
or
|
||||
// invocation of a chainable method
|
||||
exists(API::CallNode mcn, string m |
|
||||
exists(DataFlow::MethodCallNode mcn, string m |
|
||||
m = "adapter" or
|
||||
m = "attach" or
|
||||
m = "bind" or
|
||||
@@ -73,15 +72,16 @@ module SocketIO {
|
||||
m = "set" or
|
||||
m = EventEmitter::chainableMethod()
|
||||
|
|
||||
mcn = pred.getMember(m).getACall() and
|
||||
mcn = pred.getAMethodCall(m) and
|
||||
// exclude getter versions
|
||||
exists(mcn.getAnArgument()) and
|
||||
result = mcn.getReturn()
|
||||
result = mcn and
|
||||
t = t2.continue()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::SourceNode ref() { result = this.server().getAUse() }
|
||||
override DataFlow::SourceNode ref() { result = this.server(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Always returns `this` as a `ServerObject` now represents the origin of a server.
|
||||
@@ -121,49 +121,54 @@ module SocketIO {
|
||||
*/
|
||||
class NamespaceBase extends SocketIOObject {
|
||||
NamespaceObject ns;
|
||||
API::Node node;
|
||||
|
||||
NamespaceBase() {
|
||||
this = node.getAnImmediateUse() and
|
||||
exists(ServerObject srv |
|
||||
// namespace lookup on `srv`
|
||||
node = srv.asApiNode().getMember("sockets") and
|
||||
this = srv.ref().getAPropertyRead("sockets") and
|
||||
ns = srv.getDefaultNamespace()
|
||||
or
|
||||
exists(API::CallNode mcn, string path |
|
||||
mcn = srv.asApiNode().getMember("of").getACall() and
|
||||
exists(DataFlow::MethodCallNode mcn, string path |
|
||||
mcn = srv.ref().getAMethodCall("of") and
|
||||
mcn.getArgument(0).mayHaveStringValue(path) and
|
||||
node = mcn.getReturn() and
|
||||
this = mcn and
|
||||
ns = MkNamespace(srv, path)
|
||||
)
|
||||
or
|
||||
// invocation of a method that `srv` forwards to its default namespace
|
||||
node = srv.asApiNode().getMember(namespaceChainableMethod()).getReturn() and
|
||||
this = srv.ref().getAMethodCall(namespaceChainableMethod()) and
|
||||
ns = srv.getDefaultNamespace()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the API node for this namespace. */
|
||||
API::Node asApiNode() { result = node }
|
||||
|
||||
override NamespaceObject getNamespace() { result = ns }
|
||||
|
||||
/**
|
||||
* Gets a data flow node that may refer to the socket.io namespace created at `ns`.
|
||||
*/
|
||||
private API::Node namespace() {
|
||||
result = node
|
||||
private DataFlow::SourceNode namespace(DataFlow::TypeTracker t) {
|
||||
t.start() and result = this
|
||||
or
|
||||
exists(API::Node pred | pred = this.namespace() |
|
||||
exists(DataFlow::SourceNode pred, DataFlow::TypeTracker t2 | pred = this.namespace(t2) |
|
||||
result = pred.track(t2, t)
|
||||
or
|
||||
// invocation of a chainable method
|
||||
result = pred.getMember(namespaceChainableMethod()).getReturn()
|
||||
result = pred.getAMethodCall(namespaceChainableMethod()) and
|
||||
t = t2.continue()
|
||||
or
|
||||
// invocation of chainable getter method
|
||||
result = pred.getMember(["json", "local", "volatile"])
|
||||
exists(string m |
|
||||
m = "json" or
|
||||
m = "local" or
|
||||
m = "volatile"
|
||||
|
|
||||
result = pred.getAPropertyRead(m) and
|
||||
t = t2.continue()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::SourceNode ref() { result = this.namespace().getAUse() }
|
||||
override DataFlow::SourceNode ref() { result = this.namespace(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/** A data flow node that may produce a namespace object. */
|
||||
|
||||
@@ -8,37 +8,39 @@ import javascript
|
||||
* Provides classes for working with [parse-torrent](https://github.com/webtorrent/parse-torrent) code.
|
||||
*/
|
||||
module ParseTorrent {
|
||||
private API::Node mod() { result = API::moduleImport("parse-torrent") }
|
||||
private DataFlow::SourceNode mod() { result = DataFlow::moduleImport("parse-torrent") }
|
||||
|
||||
/**
|
||||
* A torrent that has been parsed into a JavaScript object.
|
||||
*/
|
||||
class ParsedTorrent extends DataFlow::SourceNode {
|
||||
API::Node node;
|
||||
|
||||
ParsedTorrent() {
|
||||
(
|
||||
node = mod().getReturn() or
|
||||
node = mod().getMember("remote").getParameter(1).getParameter(1)
|
||||
) and
|
||||
this = node.getAnImmediateUse()
|
||||
this = mod().getACall() or
|
||||
this = mod().getAMemberCall("remote").getCallback(1).getParameter(1)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the API node for this torrent object. */
|
||||
API::Node asApiNode() { result = node }
|
||||
private DataFlow::SourceNode parsedTorrentRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result instanceof ParsedTorrent
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = parsedTorrentRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a data flow node referring to a parsed torrent. */
|
||||
DataFlow::SourceNode parsedTorrentRef() { result = any(ParsedTorrent t).asApiNode().getAUse() }
|
||||
DataFlow::SourceNode parsedTorrentRef() {
|
||||
result = parsedTorrentRef(DataFlow::TypeTracker::end())
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to user-controlled torrent information.
|
||||
*/
|
||||
class UserControlledTorrentInfo extends RemoteFlowSource instanceof DataFlow::PropRead {
|
||||
class UserControlledTorrentInfo extends RemoteFlowSource {
|
||||
UserControlledTorrentInfo() {
|
||||
exists(API::Node read |
|
||||
read = any(ParsedTorrent t).asApiNode().getAMember() and
|
||||
this = read.getAnImmediateUse()
|
||||
exists(DataFlow::SourceNode ref, DataFlow::PropRead read |
|
||||
ref = parsedTorrentRef() and
|
||||
read = ref.getAPropertyRead() and
|
||||
this = read
|
||||
|
|
||||
exists(string prop |
|
||||
not (
|
||||
@@ -47,10 +49,10 @@ module ParseTorrent {
|
||||
prop = "length"
|
||||
// "pieceLength" and "lastPieceLength" are not guaranteed to be numbers as of commit ae3ad15d
|
||||
) and
|
||||
super.getPropertyName() = prop
|
||||
read.getPropertyName() = prop
|
||||
)
|
||||
or
|
||||
not exists(super.getPropertyName())
|
||||
not exists(read.getPropertyName())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -110,16 +110,6 @@ module TaintedObject {
|
||||
}
|
||||
}
|
||||
|
||||
/** A guard that checks whether `x` is a number. */
|
||||
class NumberGuard extends SanitizerGuard instanceof DataFlow::CallNode {
|
||||
Expr x;
|
||||
boolean polarity;
|
||||
|
||||
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
|
||||
}
|
||||
|
||||
/**
|
||||
* A sanitizer guard that validates an input against a JSON schema.
|
||||
*/
|
||||
|
||||
@@ -122,7 +122,6 @@ class Configuration extends TaintTracking::Configuration {
|
||||
guard instanceof InstanceofCheck or
|
||||
guard instanceof IsArrayCheck or
|
||||
guard instanceof TypeofCheck or
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof EqualityCheck or
|
||||
guard instanceof IncludesCheck
|
||||
}
|
||||
@@ -229,16 +228,6 @@ private class TypeofCheck extends TaintTracking::LabeledSanitizerGuardNode, Data
|
||||
}
|
||||
}
|
||||
|
||||
/** A guard that checks whether `x` is a number. */
|
||||
class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode {
|
||||
Expr x;
|
||||
boolean polarity;
|
||||
|
||||
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
|
||||
}
|
||||
|
||||
/** A call to `Array.isArray`, which is false for `Object.prototype`. */
|
||||
private class IsArrayCheck extends TaintTracking::LabeledSanitizerGuardNode, DataFlow::CallNode {
|
||||
IsArrayCheck() { this = DataFlow::globalVarRef("Array").getAMemberCall("isArray") }
|
||||
|
||||
@@ -153,16 +153,6 @@ module UnsafeJQueryPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/** A guard that checks whether `x` is a number. */
|
||||
class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode {
|
||||
Expr x;
|
||||
boolean polarity;
|
||||
|
||||
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
|
||||
}
|
||||
|
||||
/**
|
||||
* The client-provided options object for a jQuery plugin, considered as a source for unsafe jQuery plugins.
|
||||
*/
|
||||
|
||||
@@ -46,8 +46,7 @@ class Configuration extends TaintTracking::Configuration {
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
|
||||
super.isSanitizerGuard(node) or
|
||||
node instanceof IsElementSanitizer or
|
||||
node instanceof PropertyPresenceSanitizer or
|
||||
node instanceof NumberGuard
|
||||
node instanceof PropertyPresenceSanitizer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -286,16 +286,6 @@ module UnsafeShellCommandConstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/** A guard that checks whether `x` is a number. */
|
||||
class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode {
|
||||
Expr x;
|
||||
boolean polarity;
|
||||
|
||||
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
|
||||
}
|
||||
|
||||
private import semmle.javascript.dataflow.internal.AccessPaths
|
||||
private import semmle.javascript.dataflow.InferredTypes
|
||||
|
||||
|
||||
@@ -24,9 +24,7 @@ class Configuration extends TaintTracking::Configuration {
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof PathExistsSanitizerGuard or
|
||||
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer or
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof TypeOfSanitizer
|
||||
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer
|
||||
}
|
||||
|
||||
// override to require that there is a path without unmatched return steps
|
||||
|
||||
@@ -108,14 +108,4 @@ module UnvalidatedDynamicMethodCall {
|
||||
label instanceof MaybeNonFunction
|
||||
}
|
||||
}
|
||||
|
||||
/** A guard that checks whether `x` is a number. */
|
||||
class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode {
|
||||
Expr x;
|
||||
boolean polarity;
|
||||
|
||||
NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) }
|
||||
|
||||
override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,11 +40,6 @@ class Configuration extends TaintTracking::Configuration {
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node nd) { super.isSanitizer(nd) }
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof FunctionCheck
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
|
||||
@@ -28,7 +28,6 @@ class Configuration extends TaintTracking::Configuration {
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TypeTestGuard or
|
||||
guard instanceof UnsafeJQuery::PropertyPresenceSanitizer or
|
||||
guard instanceof UnsafeJQuery::NumberGuard or
|
||||
guard instanceof DomBasedXss::SanitizerGuard
|
||||
}
|
||||
|
||||
|
||||
@@ -1,477 +0,0 @@
|
||||
/*** Standard fragments ***/
|
||||
|
||||
/** Files and folders **/
|
||||
|
||||
@location = @location_default;
|
||||
|
||||
locations_default(unique int id: @location_default,
|
||||
int file: @file ref,
|
||||
int beginLine: int ref,
|
||||
int beginColumn: int ref,
|
||||
int endLine: int ref,
|
||||
int endColumn: int ref
|
||||
);
|
||||
|
||||
@sourceline = @toplevel;
|
||||
|
||||
numlines(int element_id: @sourceline ref,
|
||||
int num_lines: int ref,
|
||||
int num_code: int ref,
|
||||
int num_comment: int ref
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
fromSource(0) = unknown,
|
||||
fromSource(1) = from source,
|
||||
fromSource(2) = from library
|
||||
*/
|
||||
files(unique int id: @file,
|
||||
varchar(900) name: string ref,
|
||||
varchar(900) simple: string ref,
|
||||
varchar(900) ext: string ref,
|
||||
int fromSource: int ref);
|
||||
|
||||
folders(unique int id: @folder,
|
||||
varchar(900) name: string ref,
|
||||
varchar(900) simple: string ref);
|
||||
|
||||
|
||||
@container = @folder | @file ;
|
||||
|
||||
|
||||
containerparent(int parent: @container ref,
|
||||
unique int child: @container ref);
|
||||
|
||||
/** Duplicate code **/
|
||||
|
||||
duplicateCode(
|
||||
unique int id : @duplication,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
similarCode(
|
||||
unique int id : @similarity,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
@duplication_or_similarity = @duplication | @similarity;
|
||||
|
||||
tokens(
|
||||
int id : @duplication_or_similarity ref,
|
||||
int offset : int ref,
|
||||
int beginLine : int ref,
|
||||
int beginColumn : int ref,
|
||||
int endLine : int ref,
|
||||
int endColumn : int ref);
|
||||
|
||||
/** External data **/
|
||||
|
||||
externalDefects(
|
||||
unique int id : @externalDefect,
|
||||
varchar(900) queryPath : string ref,
|
||||
int location : @location ref,
|
||||
varchar(900) message : string ref,
|
||||
float severity : float ref
|
||||
);
|
||||
|
||||
externalMetrics(
|
||||
unique int id : @externalMetric,
|
||||
varchar(900) queryPath : string ref,
|
||||
int location : @location ref,
|
||||
float value : float ref
|
||||
);
|
||||
|
||||
externalData(
|
||||
int id : @externalDataElement,
|
||||
varchar(900) path : string ref,
|
||||
int column: int ref,
|
||||
varchar(900) value : string ref
|
||||
);
|
||||
|
||||
snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
/** Version control data **/
|
||||
|
||||
svnentries(
|
||||
int id : @svnentry,
|
||||
varchar(500) revision : string ref,
|
||||
varchar(500) author : string ref,
|
||||
date revisionDate : date ref,
|
||||
int changeSize : int ref
|
||||
);
|
||||
|
||||
svnaffectedfiles(
|
||||
int id : @svnentry ref,
|
||||
int file : @file ref,
|
||||
varchar(500) action : string ref
|
||||
);
|
||||
|
||||
svnentrymsg(
|
||||
int id : @svnentry ref,
|
||||
varchar(500) message : string ref
|
||||
);
|
||||
|
||||
svnchurn(
|
||||
int commit : @svnentry ref,
|
||||
int file : @file ref,
|
||||
int churnedLines : int ref
|
||||
);
|
||||
|
||||
|
||||
/*** JavaScript-specific part ***/
|
||||
|
||||
// top-level code fragments
|
||||
toplevels (unique int id: @toplevel,
|
||||
int kind: int ref);
|
||||
|
||||
case @toplevel.kind of
|
||||
0 = @script
|
||||
| 1 = @inline_script
|
||||
| 2 = @event_handler
|
||||
| 3 = @javascript_url;
|
||||
|
||||
// statements
|
||||
stmts (unique int id: @stmt,
|
||||
int kind: int ref,
|
||||
int parent: @stmtparent ref,
|
||||
int idx: int ref,
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
stmtContainers (int stmt: @stmt ref,
|
||||
int container: @stmt_container ref);
|
||||
|
||||
semicolonInserted (int stmt: @stmt ref);
|
||||
|
||||
jumpTargets (int jump: @stmt ref,
|
||||
int target: @stmt ref);
|
||||
|
||||
@stmtparent = @stmt | @toplevel | @functionexpr;
|
||||
@stmt_container = @toplevel | @functiondecl;
|
||||
|
||||
case @stmt.kind of
|
||||
0 = @emptystmt
|
||||
| 1 = @blockstmt
|
||||
| 2 = @exprstmt
|
||||
| 3 = @ifstmt
|
||||
| 4 = @labeledstmt
|
||||
| 5 = @breakstmt
|
||||
| 6 = @continuestmt
|
||||
| 7 = @withstmt
|
||||
| 8 = @switchstmt
|
||||
| 9 = @returnstmt
|
||||
| 10 = @throwstmt
|
||||
| 11 = @trystmt
|
||||
| 12 = @whilestmt
|
||||
| 13 = @dowhilestmt
|
||||
| 14 = @forstmt
|
||||
| 15 = @forinstmt
|
||||
| 16 = @debuggerstmt
|
||||
| 17 = @functiondeclstmt
|
||||
| 18 = @vardeclstmt
|
||||
| 19 = @case
|
||||
| 20 = @catchclause
|
||||
;
|
||||
|
||||
// expressions
|
||||
exprs (unique int id: @expr,
|
||||
int kind: int ref,
|
||||
int parent: @exprparent ref,
|
||||
int idx: int ref,
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
literals (varchar(900) value: string ref,
|
||||
varchar(900) raw: string ref,
|
||||
unique int expr: @expr ref);
|
||||
|
||||
enclosingStmt (int expr: @expr ref,
|
||||
int stmt: @stmt ref);
|
||||
|
||||
arraySize (int ae: @arrayexpr ref,
|
||||
int sz: int ref);
|
||||
|
||||
@exprparent = @expr | @stmt | @property | @vardeclarator;
|
||||
|
||||
case @expr.kind of
|
||||
0 = @identifier
|
||||
| 1 = @nullliteral
|
||||
| 2 = @booleanliteral
|
||||
| 3 = @numberliteral
|
||||
| 4 = @stringliteral
|
||||
| 5 = @regexpliteral
|
||||
| 6 = @thisexpr
|
||||
| 7 = @arrayexpr
|
||||
| 8 = @objexpr
|
||||
| 9 = @functionexpr
|
||||
| 10 = @seqexpr
|
||||
| 11 = @conditionalexpr
|
||||
| 12 = @newexpr
|
||||
| 13 = @callexpr
|
||||
| 14 = @dotexpr
|
||||
| 15 = @indexexpr
|
||||
| 16 = @negexpr
|
||||
| 17 = @plusexpr
|
||||
| 18 = @lognotexpr
|
||||
| 19 = @bitnotexpr
|
||||
| 20 = @typeofexpr
|
||||
| 21 = @voidexpr
|
||||
| 22 = @deleteexpr
|
||||
| 23 = @eqexpr
|
||||
| 24 = @neqexpr
|
||||
| 25 = @eqqexpr
|
||||
| 26 = @neqqexpr
|
||||
| 27 = @ltexpr
|
||||
| 28 = @leexpr
|
||||
| 29 = @gtexpr
|
||||
| 30 = @geexpr
|
||||
| 31 = @lshiftexpr
|
||||
| 32 = @rshiftexpr
|
||||
| 33 = @urshiftexpr
|
||||
| 34 = @addexpr
|
||||
| 35 = @subexpr
|
||||
| 36 = @mulexpr
|
||||
| 37 = @divexpr
|
||||
| 38 = @modexpr
|
||||
| 39 = @bitorexpr
|
||||
| 40 = @xorexpr
|
||||
| 41 = @bitandexpr
|
||||
| 42 = @inexpr
|
||||
| 43 = @instanceofexpr
|
||||
| 44 = @logandexpr
|
||||
| 45 = @logorexpr
|
||||
| 47 = @assignexpr
|
||||
| 48 = @assignaddexpr
|
||||
| 49 = @assignsubexpr
|
||||
| 50 = @assignmulexpr
|
||||
| 51 = @assigndivexpr
|
||||
| 52 = @assignmodexpr
|
||||
| 53 = @assignlshiftexpr
|
||||
| 54 = @assignrshiftexpr
|
||||
| 55 = @assignurshiftexpr
|
||||
| 56 = @assignorexpr
|
||||
| 57 = @assignxorexpr
|
||||
| 58 = @assignandexpr
|
||||
| 59 = @preincexpr
|
||||
| 60 = @postincexpr
|
||||
| 61 = @predecexpr
|
||||
| 62 = @postdecexpr
|
||||
| 63 = @parexpr
|
||||
;
|
||||
|
||||
@literal = @nullliteral | @booleanliteral | @numberliteral | @stringliteral | @regexpliteral;
|
||||
|
||||
@propaccess = @dotexpr | @indexexpr;
|
||||
|
||||
@invokeexpr = @newexpr | @callexpr;
|
||||
|
||||
@unaryexpr = @negexpr | @plusexpr | @lognotexpr | @bitnotexpr | @typeofexpr | @voidexpr | @deleteexpr;
|
||||
|
||||
@equalitytest = @eqexpr | @neqexpr | @eqqexpr | @neqqexpr;
|
||||
|
||||
@comparison = @equalitytest | @ltexpr | @leexpr | @gtexpr | @geexpr;
|
||||
|
||||
@binaryexpr = @comparison | @lshiftexpr | @rshiftexpr | @urshiftexpr | @addexpr | @subexpr | @mulexpr | @divexpr | @modexpr | @bitorexpr | @xorexpr | @bitandexpr | @inexpr | @instanceofexpr | @logandexpr | @logorexpr;
|
||||
|
||||
@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr;
|
||||
|
||||
@updateexpr = @preincexpr | @postincexpr | @predecexpr | @postdecexpr;
|
||||
|
||||
// scopes
|
||||
scopes (unique int id: @scope,
|
||||
int kind: int ref);
|
||||
|
||||
case @scope.kind of
|
||||
0 = @globalscope
|
||||
| 1 = @functionscope
|
||||
| 2 = @catchscope
|
||||
| 3 = @modulescope;
|
||||
|
||||
@scopenode = @functiondecl | @catchclause | @script;
|
||||
|
||||
scopenodes (int node: @scopenode ref,
|
||||
int scope: @scope ref);
|
||||
|
||||
scopenesting (int inner: @scope ref,
|
||||
int outer: @scope ref);
|
||||
|
||||
// functions
|
||||
@functiondecl = @functiondeclstmt | @functionexpr;
|
||||
|
||||
@parameterized = @functiondecl | @catchclause;
|
||||
|
||||
params (unique int id: @param,
|
||||
int variable: @variable ref,
|
||||
varchar(900) name: string ref,
|
||||
int pos: int ref,
|
||||
int parent: @parameterized ref);
|
||||
|
||||
// variables
|
||||
variables (unique int id: @variable,
|
||||
varchar(900) name: string ref,
|
||||
int scope: @scope ref);
|
||||
|
||||
isArgumentsObject (int id: @variable ref);
|
||||
|
||||
vardecls (unique int id: @vardeclarator,
|
||||
int variable: @variable ref,
|
||||
int parent: @stmt ref,
|
||||
int pos: int ref,
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
// function declaration statements and named function expressions implicitly
|
||||
// declare variables; this table links the function declaration with its variable
|
||||
functionvars (int func: @functiondecl ref,
|
||||
int var: @variable ref);
|
||||
|
||||
bind (int id: @identifier ref,
|
||||
int decl: @variable ref);
|
||||
|
||||
@vardeclaration = @param | @vardeclarator | @functiondecl;
|
||||
|
||||
// properties in object literals
|
||||
properties (unique int id: @property,
|
||||
int parent: @objexpr ref,
|
||||
int index: int ref,
|
||||
int kind: int ref, // 0 - normal, 1 - getter, 2 - setter
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
// comments
|
||||
comments (unique int id: @comment,
|
||||
int kind: int ref,
|
||||
int toplevel: @toplevel ref,
|
||||
varchar(900) text: string ref,
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
case @comment.kind of
|
||||
0 = @slashslashcomment
|
||||
| 1 = @slashstarcomment
|
||||
| 2 = @doccomment
|
||||
| 3 = @htmlcommentstart
|
||||
| 4 = @htmlcommentend;
|
||||
|
||||
@htmlcomment = @htmlcommentstart | @htmlcommentend;
|
||||
@linecomment = @slashslashcomment | @htmlcomment;
|
||||
@blockcomment = @slashstarcomment | @doccomment;
|
||||
|
||||
// source lines
|
||||
lines (unique int id: @line,
|
||||
int toplevel: @toplevel ref,
|
||||
varchar(900) text: string ref,
|
||||
varchar(2) terminator: string ref);
|
||||
|
||||
// errors
|
||||
errors (unique int id: @error,
|
||||
int kind: int ref,
|
||||
int toplevel: @toplevel ref,
|
||||
varchar(900) message: string ref);
|
||||
|
||||
case @error.kind of
|
||||
0 = @parseerror;
|
||||
|
||||
// regular expressions
|
||||
regexpterm (unique int id: @regexpterm,
|
||||
int kind: int ref,
|
||||
int parent: @regexpparent ref,
|
||||
int idx: int ref,
|
||||
varchar(900) tostring: string ref);
|
||||
|
||||
@regexpparent = @regexpterm | @regexpliteral;
|
||||
|
||||
case @regexpterm.kind of
|
||||
0 = @regexp_alt
|
||||
| 1 = @regexp_seq
|
||||
| 2 = @regexp_caret
|
||||
| 3 = @regexp_dollar
|
||||
| 4 = @regexp_wordboundary
|
||||
| 5 = @regexp_nonwordboundary
|
||||
| 6 = @regexp_positive_lookahead
|
||||
| 7 = @regexp_negative_lookahead
|
||||
| 8 = @regexp_star
|
||||
| 9 = @regexp_plus
|
||||
| 10 = @regexp_opt
|
||||
| 11 = @regexp_range
|
||||
| 12 = @regexp_dot
|
||||
| 13 = @regexp_group
|
||||
| 14 = @regexp_normal_char
|
||||
| 15 = @regexp_hex_escape
|
||||
| 16 = @regexp_unicode_escape
|
||||
| 17 = @regexp_dec_escape
|
||||
| 18 = @regexp_oct_escape
|
||||
| 19 = @regexp_ctrl_escape
|
||||
| 20 = @regexp_char_class_escape
|
||||
| 21 = @regexp_id_escape
|
||||
| 22 = @regexp_backref
|
||||
| 23 = @regexp_char_class
|
||||
| 24 = @regexp_char_range;
|
||||
|
||||
regexpParseErrors (unique int id: @regexp_parse_error,
|
||||
int kind: int ref,
|
||||
int regexp: @regexpterm ref);
|
||||
|
||||
case @regexp_parse_error.kind of
|
||||
0 = @regexp_parse_error_unexpected_eos
|
||||
| 1 = @regexp_parse_error_unexpected_char
|
||||
| 2 = @regexp_parse_error_expected_digit
|
||||
| 3 = @regexp_parse_error_expected_hex_digit
|
||||
| 4 = @regexp_parse_error_expected_control_letter
|
||||
| 5 = @regexp_parse_error_expected_closing_paren
|
||||
| 6 = @regexp_parse_error_expected_closing_brace
|
||||
| 7 = @regexp_parse_error_expected_eos
|
||||
| 8 = @regexp_parse_error_octal_escape
|
||||
| 9 = @regexp_parse_error_invalid_backref;
|
||||
|
||||
@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
|
||||
@regexp_escape = @regexp_char_escape | @regexp_char_class_escape;
|
||||
@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
|
||||
@regexp_constant = @regexp_normal_char | @regexp_char_escape;
|
||||
|
||||
isGreedy (int id: @regexp_quantifier ref);
|
||||
rangeQuantifierLowerBound (int id: @regexp_range ref, int lo: int ref);
|
||||
rangeQuantifierUpperBound (int id: @regexp_range ref, int hi: int ref);
|
||||
isCapture (int id: @regexp_group ref, int number: int ref);
|
||||
isInverted (int id: @regexp_char_class ref);
|
||||
regexpConstValue (int id: @regexp_constant ref, varchar(1) value: string ref);
|
||||
charClassEscape (int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
|
||||
backref (int id: @regexp_backref ref, int value: int ref);
|
||||
|
||||
// tokens
|
||||
tokeninfo (unique int id: @token,
|
||||
int kind: int ref,
|
||||
int toplevel: @toplevel ref,
|
||||
int idx: int ref,
|
||||
varchar(900) value: string ref);
|
||||
|
||||
case @token.kind of
|
||||
0 = @token_eof
|
||||
| 1 = @token_null_literal
|
||||
| 2 = @token_boolean_literal
|
||||
| 3 = @token_numeric_literal
|
||||
| 4 = @token_string_literal
|
||||
| 5 = @token_regular_expression
|
||||
| 6 = @token_identifier
|
||||
| 7 = @token_keyword
|
||||
| 8 = @token_punctuator;
|
||||
|
||||
// locations
|
||||
@locatable = @file
|
||||
| @toplevel | @stmt | @expr | @property | @vardeclaration
|
||||
| @comment
|
||||
| @line
|
||||
| @error | @regexp_parse_error
|
||||
| @regexpterm
|
||||
| @token;
|
||||
|
||||
hasLocation (int locatable: @locatable ref,
|
||||
int location: @location ref);
|
||||
|
||||
// Closure externs
|
||||
external_global (unique int id: @external_global, varchar(900) name: string ref);
|
||||
external_member (unique int id: @external_member, varchar(900) name: string ref, int parent: @external_entity ref);
|
||||
|
||||
external_function (unique int id: @external_function, int decl: @external_decl ref);
|
||||
external_object (unique int id: @external_object, int decl: @external_decl ref);
|
||||
|
||||
@external_decl = @external_global | @external_member;
|
||||
@external_entity = @external_function | @external_object;
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.0.10
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query, `js/unsafe-code-construction`, has been added to the query suite, highlighting libraries that may leave clients vulnerable to arbitary code execution.
|
||||
The query is not run by default.
|
||||
* A new query `js/file-system-race` has been added. The query detects when there is time between a file being checked and used. The query is not run by default.
|
||||
* A new query `js/jwt-missing-verification` has been added. The query detects applications that don't verify JWT tokens.
|
||||
* The `js/insecure-dependency` query has been added. It detects depedencies that are downloaded using an unencrypted connection.
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### New Queries
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* The `js/insecure-dependency` query has been added. It detects depedencies that are downloaded using an unencrypted connection.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* A new query `js/jwt-missing-verification` has been added. The query detects applications that don't verify JWT tokens.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* A new query `js/file-system-race` has been added. The query detects when there is time between a file being checked and used. The query is not run by default.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* A new query, `js/unsafe-code-construction`, has been added to the query suite, highlighting libraries that may leave clients vulnerable to arbitary code execution.
|
||||
The query is not run by default.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added dataflow through the [`snapdragon`](https://npmjs.com/package/snapdragon) library.
|
||||
9
javascript/ql/src/change-notes/released/0.0.10.md
Normal file
9
javascript/ql/src/change-notes/released/0.0.10.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 0.0.10
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query, `js/unsafe-code-construction`, has been added to the query suite, highlighting libraries that may leave clients vulnerable to arbitary code execution.
|
||||
The query is not run by default.
|
||||
* A new query `js/file-system-race` has been added. The query detects when there is time between a file being checked and used. The query is not run by default.
|
||||
* A new query `js/jwt-missing-verification` has been added. The query detects applications that don't verify JWT tokens.
|
||||
* The `js/insecure-dependency` query has been added. It detects depedencies that are downloaded using an unencrypted connection.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.9
|
||||
lastReleaseVersion: 0.0.10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-queries
|
||||
version: 0.0.10-dev
|
||||
version: 0.0.10
|
||||
groups:
|
||||
- javascript
|
||||
- queries
|
||||
|
||||
@@ -2,7 +2,6 @@ test_CheerioRef
|
||||
| tst.js:1:1:1:30 | import ... eerio"; |
|
||||
| tst.js:1:8:1:14 | cheerio |
|
||||
| tst.js:4:11:4:23 | getTemplate() |
|
||||
| tst.js:8:1:10:1 | return of function getTemplate |
|
||||
| tst.js:9:10:9:36 | cheerio ... t</b>') |
|
||||
test_CheerioObjectCreation
|
||||
| tst.js:5:3:5:18 | $.attr('foo', 5) |
|
||||
|
||||
@@ -34,9 +34,6 @@
|
||||
| lib/lib.js:28:3:28:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/moduleLib/moduleLib.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
|
||||
| lib/otherLib/js/src/index.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
|
||||
| lib/snapdragon.js:7:28:7:29 | a* | Strings starting with 'a' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding aa*$ |
|
||||
| lib/snapdragon.js:15:26:15:27 | a* | Strings starting with 'a' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding aa*$ |
|
||||
| lib/snapdragon.js:23:22:23:23 | a* | Strings starting with 'a' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding aa*$ |
|
||||
| lib/sublib/factory.js:13:14:13:15 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| polynomial-redos.js:7:24:7:26 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
|
||||
| polynomial-redos.js:8:17:8:18 | * | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding *, * |
|
||||
|
||||
@@ -30,23 +30,6 @@ nodes
|
||||
| lib/otherLib/js/src/index.js:1:28:1:31 | name |
|
||||
| lib/otherLib/js/src/index.js:2:13:2:16 | name |
|
||||
| lib/otherLib/js/src/index.js:2:13:2:16 | name |
|
||||
| lib/snapdragon.js:3:34:3:38 | input |
|
||||
| lib/snapdragon.js:3:34:3:38 | input |
|
||||
| lib/snapdragon.js:7:15:7:18 | this |
|
||||
| lib/snapdragon.js:7:15:7:18 | this |
|
||||
| lib/snapdragon.js:9:12:9:16 | input |
|
||||
| lib/snapdragon.js:12:34:12:38 | input |
|
||||
| lib/snapdragon.js:12:34:12:38 | input |
|
||||
| lib/snapdragon.js:15:13:15:16 | this |
|
||||
| lib/snapdragon.js:15:13:15:16 | this |
|
||||
| lib/snapdragon.js:17:20:17:24 | input |
|
||||
| lib/snapdragon.js:20:34:20:38 | input |
|
||||
| lib/snapdragon.js:20:34:20:38 | input |
|
||||
| lib/snapdragon.js:22:44:22:47 | node |
|
||||
| lib/snapdragon.js:23:5:23:8 | node |
|
||||
| lib/snapdragon.js:23:5:23:12 | node.val |
|
||||
| lib/snapdragon.js:23:5:23:12 | node.val |
|
||||
| lib/snapdragon.js:25:22:25:26 | input |
|
||||
| lib/sublib/factory.js:12:26:12:29 | name |
|
||||
| lib/sublib/factory.js:12:26:12:29 | name |
|
||||
| lib/sublib/factory.js:13:24:13:27 | name |
|
||||
@@ -224,20 +207,6 @@ edges
|
||||
| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name |
|
||||
| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name |
|
||||
| lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name |
|
||||
| lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input |
|
||||
| lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:9:12:9:16 | input |
|
||||
| lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this |
|
||||
| lib/snapdragon.js:9:12:9:16 | input | lib/snapdragon.js:7:15:7:18 | this |
|
||||
| lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input |
|
||||
| lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:17:20:17:24 | input |
|
||||
| lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this |
|
||||
| lib/snapdragon.js:17:20:17:24 | input | lib/snapdragon.js:15:13:15:16 | this |
|
||||
| lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input |
|
||||
| lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:25:22:25:26 | input |
|
||||
| lib/snapdragon.js:22:44:22:47 | node | lib/snapdragon.js:23:5:23:8 | node |
|
||||
| lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val |
|
||||
| lib/snapdragon.js:23:5:23:8 | node | lib/snapdragon.js:23:5:23:12 | node.val |
|
||||
| lib/snapdragon.js:25:22:25:26 | input | lib/snapdragon.js:22:44:22:47 | node |
|
||||
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
|
||||
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
|
||||
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
|
||||
@@ -386,9 +355,6 @@ edges
|
||||
| lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input |
|
||||
| lib/moduleLib/moduleLib.js:2:2:2:17 | /a*b/.test(name) | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | regular expression | lib/moduleLib/moduleLib.js:1:28:1:31 | name | library input |
|
||||
| lib/otherLib/js/src/index.js:2:2:2:17 | /a*b/.test(name) | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/otherLib/js/src/index.js:2:3:2:4 | a* | regular expression | lib/otherLib/js/src/index.js:1:28:1:31 | name | library input |
|
||||
| lib/snapdragon.js:7:15:7:32 | this.match(/aa*$/) | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:7:15:7:18 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:7:28:7:29 | a* | regular expression | lib/snapdragon.js:3:34:3:38 | input | library input |
|
||||
| lib/snapdragon.js:15:13:15:30 | this.match(/aa*$/) | lib/snapdragon.js:12:34:12:38 | input | lib/snapdragon.js:15:13:15:16 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:15:26:15:27 | a* | regular expression | lib/snapdragon.js:12:34:12:38 | input | library input |
|
||||
| lib/snapdragon.js:23:5:23:26 | node.va ... /aa*$/) | lib/snapdragon.js:20:34:20:38 | input | lib/snapdragon.js:23:5:23:12 | node.val | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:23:22:23:23 | a* | regular expression | lib/snapdragon.js:20:34:20:38 | input | library input |
|
||||
| lib/sublib/factory.js:13:13:13:28 | /f*g/.test(name) | lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/sublib/factory.js:13:14:13:15 | f* | regular expression | lib/sublib/factory.js:12:26:12:29 | name | library input |
|
||||
| polynomial-redos.js:7:2:7:34 | tainted ... /g, '') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:7:2:7:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:7:24:7:26 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
|
||||
| polynomial-redos.js:8:2:8:23 | tainted ... *, */) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:8:2:8:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:8:17:8:18 | * | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
|
||||
|
||||
@@ -26,6 +26,4 @@ module.exports.id = id;
|
||||
module.exports.safe = function (x) {
|
||||
var y = id("safe");
|
||||
/f*g/.test(y); // OK
|
||||
}
|
||||
|
||||
module.exports.snapdragon = require("./snapdragon")
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
var Snapdragon = require("snapdragon");
|
||||
|
||||
module.exports.test1 = function (input) {
|
||||
var snapdragon = new Snapdragon();
|
||||
var ast = snapdragon.parser
|
||||
.set("foo", function () {
|
||||
var m = this.match(/aa*$/); // NOT OK
|
||||
})
|
||||
.parse(input, options);
|
||||
};
|
||||
|
||||
module.exports.test2 = function (input) {
|
||||
var snapdragon = new Snapdragon();
|
||||
snapdragon.parser.set("foo", function () {
|
||||
var m = this.match(/aa*$/); // NOT OK
|
||||
});
|
||||
snapdragon.parse(input, options);
|
||||
};
|
||||
|
||||
module.exports.test3 = function (input) {
|
||||
var snapdragon = new Snapdragon();
|
||||
snapdragon.compiler.set("foo", function (node) {
|
||||
node.val.match(/aa*$/); // NOT OK
|
||||
});
|
||||
snapdragon.compile(input, options);
|
||||
};
|
||||
@@ -254,24 +254,6 @@ nodes
|
||||
| lib/lib.js:498:45:498:48 | name |
|
||||
| lib/lib.js:499:31:499:34 | name |
|
||||
| lib/lib.js:499:31:499:34 | name |
|
||||
| lib/lib.js:509:39:509:42 | name |
|
||||
| lib/lib.js:509:39:509:42 | name |
|
||||
| lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:545:23:545:26 | name |
|
||||
| lib/lib.js:545:23:545:26 | name |
|
||||
| lib/subLib2/compiled-file.ts:3:26:3:29 | name |
|
||||
| lib/subLib2/compiled-file.ts:3:26:3:29 | name |
|
||||
| lib/subLib2/compiled-file.ts:4:25:4:28 | name |
|
||||
@@ -592,38 +574,6 @@ edges
|
||||
| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name |
|
||||
| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name |
|
||||
| lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name |
|
||||
| lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name |
|
||||
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
|
||||
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
|
||||
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
|
||||
@@ -716,14 +666,6 @@ edges
|
||||
| lib/lib.js:478:27:478:46 | config.installedPath | lib/lib.js:477:33:477:38 | config | lib/lib.js:478:27:478:46 | config.installedPath | $@ based on $@ is later used in $@. | lib/lib.js:478:27:478:46 | config.installedPath | Path concatenation | lib/lib.js:477:33:477:38 | config | library input | lib/lib.js:479:12:479:20 | exec(cmd) | shell command |
|
||||
| lib/lib.js:483:13:483:33 | ' my na ... + name | lib/lib.js:482:40:482:43 | name | lib/lib.js:483:30:483:33 | name | $@ based on $@ is later used in $@. | lib/lib.js:483:13:483:33 | ' my na ... + name | String concatenation | lib/lib.js:482:40:482:43 | name | library input | lib/lib.js:485:2:485:20 | cp.exec(cmd + args) | shell command |
|
||||
| lib/lib.js:499:19:499:34 | "rm -rf " + name | lib/lib.js:498:45:498:48 | name | lib/lib.js:499:31:499:34 | name | $@ based on $@ is later used in $@. | lib/lib.js:499:19:499:34 | "rm -rf " + name | String concatenation | lib/lib.js:498:45:498:48 | name | library input | lib/lib.js:499:3:499:35 | MyThing ... + name) | shell command |
|
||||
| lib/lib.js:510:10:510:25 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:510:22:510:25 | name | $@ based on $@ is later used in $@. | lib/lib.js:510:10:510:25 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:510:2:510:26 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:513:11:513:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:513:23:513:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:513:11:513:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:513:3:513:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:519:11:519:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:519:23:519:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:519:11:519:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:519:3:519:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:525:11:525:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:525:23:525:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:525:11:525:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:525:3:525:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:531:11:531:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:531:23:531:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:531:11:531:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:531:3:531:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:537:11:537:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:537:23:537:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:537:11:537:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:537:3:537:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:543:11:543:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:543:23:543:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:543:11:543:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:543:3:543:27 | cp.exec ... + name) | shell command |
|
||||
| lib/lib.js:545:11:545:26 | "rm -rf " + name | lib/lib.js:509:39:509:42 | name | lib/lib.js:545:23:545:26 | name | $@ based on $@ is later used in $@. | lib/lib.js:545:11:545:26 | "rm -rf " + name | String concatenation | lib/lib.js:509:39:509:42 | name | library input | lib/lib.js:545:3:545:27 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | $@ based on $@ is later used in $@. | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | String concatenation | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command |
|
||||
|
||||
@@ -504,44 +504,4 @@ module.exports.myCommand = function (myCommand) {
|
||||
var imp = require('./isImported');
|
||||
for (var name in imp){
|
||||
module.exports[name] = imp[name];
|
||||
}
|
||||
|
||||
module.exports.sanitizer4 = function (name) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
|
||||
if (isNaN(name)) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // OK
|
||||
}
|
||||
|
||||
if (isNaN(parseInt(name))) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // OK
|
||||
}
|
||||
|
||||
if (isNaN(+name)) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // OK
|
||||
}
|
||||
|
||||
if (isNaN(parseInt(name, 10))) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // OK
|
||||
}
|
||||
|
||||
if (isNaN(name - 0)) {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // OK
|
||||
}
|
||||
|
||||
if (isNaN(name | 0)) { // <- not a sanitizer
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
} else {
|
||||
cp.exec("rm -rf " + name); // NOT OK
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.0.9
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user