Compare commits

..

4 Commits

Author SHA1 Message Date
Arthur Baars
74ed89409c Merge pull request #7948 from github/release-prep/2.8.1
Release preparation for version 2.8.1
2022-02-11 10:13:34 +01:00
Arthur Baars
58a2597c3a C++: move change note lines to correct query pack 2022-02-11 09:52:36 +01:00
Tamás Vajk
c5d917eb72 Improve formatting of 0.0.9 release notes 2022-02-11 09:19:43 +01:00
github-actions[bot]
f25fc70b7c Release preparation for version 2.8.1 2022-02-10 22:08:24 +00:00
126 changed files with 2176 additions and 4684 deletions

6
.gitattributes vendored
View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,5 @@
## 0.0.9
## 0.0.8
### Deprecated APIs

View File

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

View File

@@ -0,0 +1,2 @@
## 0.0.9

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

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

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `cpp/cleartext-storage-buffer` query has been updated to use the `semmle.code.cpp.dataflow.TaintTracking` library.

View File

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

View File

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

View File

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

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.0.9-dev
version: 0.0.9
groups:
- cpp
- queries

View File

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

View File

@@ -1,3 +1,5 @@
## 1.0.3
## 1.0.2
## 1.0.0

View File

@@ -0,0 +1 @@
## 1.0.3

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.2
lastReleaseVersion: 1.0.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.0.3-dev
version: 1.0.3
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,5 @@
## 1.0.3
## 1.0.2
## 1.0.0

View File

@@ -0,0 +1 @@
## 1.0.3

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.2
lastReleaseVersion: 1.0.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.0.3-dev
version: 1.0.3
groups:
- csharp
- solorigate

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
---
category: majorAnalysis
---
* Return value attributes are extracted.
* The QL `Attribute` class now has subclasses for each kind of attribute.

View File

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

View File

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

View File

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

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

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

View File

@@ -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()
)
}

View File

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

View File

@@ -1,3 +1,5 @@
## 0.0.9
## 0.0.8
## 0.0.7

View File

@@ -0,0 +1 @@
## 0.0.9

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.0.9-dev
version: 0.0.9
groups:
- csharp
- queries

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,5 @@
## 0.0.9
## 0.0.8
### Deprecated APIs

View File

@@ -0,0 +1 @@
## 0.0.9

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.8
lastReleaseVersion: 0.0.9

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 0.0.9-dev
version: 0.0.9
groups:
- java
- queries

View File

@@ -1,3 +1,5 @@
## 0.0.10
## 0.0.9
### Deprecated APIs

View File

@@ -0,0 +1 @@
## 0.0.10

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.9
lastReleaseVersion: 0.0.10

View File

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

View File

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

View File

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

View File

@@ -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()
}
}
}

View File

@@ -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")
)
}

View File

@@ -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) }
}
/**

View File

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

View File

@@ -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()
)
)
}
}
}

View File

@@ -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. */

View File

@@ -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())
)
}

View File

@@ -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.
*/

View File

@@ -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") }

View File

@@ -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.
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
---
category: newQuery
---
* The `js/insecure-dependency` query has been added. It detects depedencies that are downloaded using an unencrypted connection.

View File

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

View File

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

View File

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

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added dataflow through the [`snapdragon`](https://npmjs.com/package/snapdragon) library.

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.9
lastReleaseVersion: 0.0.10

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.0.10-dev
version: 0.0.10
groups:
- javascript
- queries

View File

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

View File

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

View File

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

View File

@@ -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")
}

View File

@@ -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);
};

View File

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

View File

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

View File

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