Skip to content

Commit 034f7cc

Browse files
committed
Merge branch 'master' into model-gets
2 parents c641a31 + 17c57dc commit 034f7cc

File tree

655 files changed

+27040
-11707
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

655 files changed

+27040
-11707
lines changed

CONTRIBUTING.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ Before we accept your pull request, we require that you have agreed to our Contr
66

77
## Adding a new query
88

9-
If you have an idea for a query that you would like to share with other Semmle users, please open a pull request to add it to this repository.
10-
Follow the steps below to help other users understand what your query does, and to ensure that your query is consistent with the other Semmle queries.
9+
If you have an idea for a query that you would like to share with other CodeQL users, please open a pull request to add it to this repository.
10+
Follow the steps below to help other users understand what your query does, and to ensure that your query is consistent with the other CodeQL queries.
1111

1212
1. **Consult the documentation for query writers**
1313

1414
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [Writing CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
1515

1616
2. **Format your code correctly**
1717

18-
All of Semmle's standard queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all contributions follow the same formatting guidelines. If you use CodeQL for VS Code, you can autoformat your query in the [Editor](https://help.semmle.com/codeql/codeql-for-vscode/reference/editor.html#autoformatting). For more information, see the [CodeQL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md).
18+
All CodeQL standard queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all contributions follow the same formatting guidelines. If you use CodeQL for VS Code, you can autoformat your query in the [Editor](https://help.semmle.com/codeql/codeql-for-vscode/reference/editor.html#autoformatting). For more information, see the [CodeQL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md).
1919

2020
3. **Make sure your query has the correct metadata**
2121

22-
Query metadata is used by Semmle's analysis to identify your query and make sure the query results are displayed properly.
22+
Query metadata is used to identify your query and make sure the query results are displayed properly.
2323
The most important metadata to include are the `@name`, `@description`, and the `@kind`.
24-
Other metadata properties (`@precision`, `@severity`, and `@tags`) are usually added after the query has been reviewed by Semmle staff.
24+
Other metadata properties (`@precision`, `@severity`, and `@tags`) are usually added after the query has been reviewed by GitHub staff.
2525
For more information on writing query metadata, see the [Query metadata style guide](https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md).
2626

2727
4. **Make sure the `select` statement is compatible with the query type**
@@ -39,13 +39,19 @@ Follow the steps below to help other users understand what your query does, and
3939
* JavaScript: `ql/javascript/ql/src`
4040
* Python: `ql/python/ql/src`
4141

42-
Each language-specific directory contains further subdirectories that group queries based on their `@tags` properties or purpose. Select the appropriate subdirectory for your new query, or create a new one if necessary.
42+
Each language-specific directory contains further subdirectories that group queries based on their `@tags` properties or purpose. Select the appropriate subdirectory for your new query, or create a new one if necessary.
4343

4444
6. **Write a query help file**
4545

46-
Query help files explain the purpose of your query to other users. Write your query help in a `.qhelp` file and save it in the same directory as your new query.
46+
Query help files explain the purpose of your query to other users. Write your query help in a `.qhelp` file and save it in the same directory as your new query.
4747
For more information on writing query help, see the [Query help style guide](https://github.com/Semmle/ql/blob/master/docs/query-help-style-guide.md).
4848

49+
7. **Maintain backwards compatibility**
50+
51+
The standard CodeQL libraries must evolve in a backwards compatible manner. If any backwards incompatible changes need to be made, the existing API must first be marked as deprecated. This is done by adding a `deprecated` annotation along with a QLDoc reference to the replacement API. Only after at least one full release cycle has elapsed may the old API be removed.
52+
53+
In addition to contributions to our standard queries and libraries, we also welcome contributions of a more experimental nature, which do not need to fulfill all the requirements listed above. See the guidelines for [experimental queries and libraries](docs/experimental.md) for details.
54+
4955
## Using your personal data
5056

5157
If you contribute to this project, we will record your name and email

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CodeQL
22

3-
This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com), and the other products that [Semmle](https://semmle.com) makes available to its customers worldwide.
3+
This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com) and the other CodeQL products that [GitHub](https://github.com) makes available to its customers worldwide.
44

55
## How do I learn CodeQL and run queries?
66

@@ -13,4 +13,4 @@ We welcome contributions to our standard library and standard checks. Do you hav
1313

1414
## License
1515

16-
The code in this repository is licensed under [Apache License 2.0](LICENSE) by [Semmle](https://semmle.com).
16+
The code in this repository is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com).

change-notes/1.24/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
1818
| No space for zero terminator (`cpp/no-space-for-terminator`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
1919
| Memory is never freed (`cpp/memory-never-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
2020
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
21+
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed false positive results in template code. |
2122
| Missing return statement (`cpp/missing-return`) | Fewer false positive results | Functions containing `asm` statements are no longer highlighted by this query. |
2223
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | String arguments to formatting functions are now (usually) expected to be null terminated strings. |
2324
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |

change-notes/1.24/analysis-java.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The following changes in version 1.24 affect Java analysis in all applications.
55
## General improvements
66

77
* Alert suppression can now be done with single-line block comments (`/* ... */`) as well as line comments (`// ...`).
8+
* A `Customizations.qll` file has been added to allow customizations of the standard library that apply to all queries.
89

910
## New queries
1011

change-notes/1.24/analysis-javascript.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## General improvements
44

5+
* TypeScript 3.8 is now supported.
6+
57
* Alert suppression can now be done with single-line block comments (`/* ... */`) as well as line comments (`// ...`).
68

79
* Imports with the `.js` extension can now be resolved to a TypeScript file,
@@ -13,7 +15,11 @@
1315

1416
* The analysis of sanitizer guards has improved, leading to fewer false-positive results from the security queries.
1517

16-
* Calls can now be resolved to class members in more cases, leading to more results from the security queries.
18+
* The call graph construction has been improved, leading to more results from the security queries:
19+
- Calls can now be resolved to indirectly-defined class members in more cases.
20+
- Calls through partial invocations such as `.bind` can now be resolved in more cases.
21+
22+
* Support for flow summaries has been more clearly marked as being experimental and moved to the new `experimental` folder.
1723

1824
* Support for the following frameworks and libraries has been improved:
1925
- [Electron](https://electronjs.org/)
@@ -26,8 +32,11 @@
2632
- [for-in](https://www.npmjs.com/package/for-in)
2733
- [for-own](https://www.npmjs.com/package/for-own)
2834
- [http2](https://nodejs.org/api/http2.html)
35+
- [jQuery](https://jquery.com/)
2936
- [lazy-cache](https://www.npmjs.com/package/lazy-cache)
37+
- [mongodb](https://www.npmjs.com/package/mongodb)
3038
- [react](https://www.npmjs.com/package/react)
39+
- [request](https://www.npmjs.com/package/request)
3140
- [send](https://www.npmjs.com/package/send)
3241
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
3342
- [ws](https://github.com/websockets/ws)
@@ -39,8 +48,11 @@
3948
| Cross-site scripting through exception (`js/xss-through-exception`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where an exception is written to the DOM. Results are not shown on LGTM by default. |
4049
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
4150
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
42-
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive copying operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
51+
| Polynomial regular expression used on uncontrolled data (`js/polynomial-redos`) | security, external/cwe/cwe-730, external/cwe/cwe-400 | Highlights expensive regular expressions that may be used on malicious input. Results are shown on LGTM by default. |
52+
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive assignment operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
4353
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
54+
| Unnecessary use of `cat` process (`js/unnecessary-use-of-cat`) | correctness, security, maintainability | Highlights command executions of `cat` where the fs API should be used instead. Results are shown on LGTM by default. |
55+
4456

4557
## Changes to existing queries
4658

@@ -53,8 +65,12 @@
5365
| Expression has no effect (`js/useless-expression`) | Fewer false positive results | The query now recognizes block-level flow type annotations and ignores the first statement of a try block. |
5466
| Use of call stack introspection in strict mode (`js/strict-mode-call-stack-introspection`) | Fewer false positive results | The query no longer flags expression statements. |
5567
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer false positive results | The query reports fewer duplicates and only flags handlers that explicitly access cookie data. |
56-
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed. |
68+
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed and used. |
5769
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional ways of constructing arguments to `cmd.exe` and `/bin/sh`. |
70+
| Syntax error (`js/syntax-error`) | Lower severity | This results of this query are now displayed with lower severity. |
71+
| Use of password hash with insufficient computational effort (`js/insufficient-password-hash`) | Fewer false positive results | This query now recognizes additional cases that do not require secure hashing. |
72+
| Useless regular-expression character escape (`js/useless-regexp-character-escape`) | Fewer false positive results | This query now distinguishes escapes in strings and regular expression literals. |
73+
| Identical operands (`js/redundant-operation`) | Fewer results | This query now recognizes cases where the operands change a value using ++/-- expressions. |
5874

5975
## Changes to libraries
6076

cpp/ql/src/Critical/NewDelete.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import semmle.code.cpp.dataflow.DataFlow
1212
*/
1313
predicate allocExpr(Expr alloc, string kind) {
1414
isAllocationExpr(alloc) and
15+
not alloc.isFromUninstantiatedTemplate(_) and
1516
(
1617
alloc instanceof FunctionCall and
1718
kind = "malloc"

cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.qll

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,33 @@ class ConstantZero extends Expr {
1515
}
1616
}
1717

18+
/**
19+
* Holds if `candidate` is an expression such that if it's unsigned then we
20+
* want an alert at `ge`.
21+
*/
22+
private predicate lookForUnsignedAt(GEExpr ge, Expr candidate) {
23+
// Base case: `candidate >= 0`
24+
ge.getRightOperand() instanceof ConstantZero and
25+
candidate = ge.getLeftOperand().getFullyConverted() and
26+
// left operand was a signed or unsigned IntegralType before conversions
27+
// (not a pointer, checking a pointer >= 0 is an entirely different mistake)
28+
// (not an enum, as the fully converted type of an enum is compiler dependent
29+
// so checking an enum >= 0 is always reasonable)
30+
ge.getLeftOperand().getUnderlyingType() instanceof IntegralType
31+
or
32+
// Recursive case: `...(largerType)candidate >= 0`
33+
exists(Conversion conversion |
34+
lookForUnsignedAt(ge, conversion) and
35+
candidate = conversion.getExpr() and
36+
conversion.getType().getSize() > candidate.getType().getSize()
37+
)
38+
}
39+
1840
class UnsignedGEZero extends GEExpr {
1941
UnsignedGEZero() {
20-
this.getRightOperand() instanceof ConstantZero and
21-
// left operand was a signed or unsigned IntegralType before conversions
22-
// (not a pointer, checking a pointer >= 0 is an entirely different mistake)
23-
// (not an enum, as the fully converted type of an enum is compiler dependent
24-
// so checking an enum >= 0 is always reasonable)
25-
getLeftOperand().getUnderlyingType() instanceof IntegralType and
2642
exists(Expr ue |
27-
// ue is some conversion of the left operand
28-
ue = getLeftOperand().getConversion*() and
29-
// ue is unsigned
30-
ue.getUnderlyingType().(IntegralType).isUnsigned() and
31-
// ue may be converted to zero or more strictly larger possibly signed types
32-
// before it is fully converted
33-
forall(Expr following | following = ue.getConversion+() |
34-
following.getType().getSize() > ue.getType().getSize()
35-
)
43+
lookForUnsignedAt(this, ue) and
44+
ue.getUnderlyingType().(IntegralType).isUnsigned()
3645
)
3746
}
3847
}

cpp/ql/src/experimental/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This directory contains [experimental](../../../../docs/experimental.md) CodeQL queries and libraries.

cpp/ql/src/semmle/code/cpp/Field.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import semmle.code.cpp.exprs.Access
1919
class Field extends MemberVariable {
2020
Field() { fieldoffsets(underlyingElement(this), _, _) }
2121

22+
override string getCanonicalQLClass() { result = "Field" }
23+
2224
/**
2325
* Gets the offset of this field in bytes from the start of its declaring
2426
* type (on the machine where facts were extracted).
@@ -84,6 +86,8 @@ class Field extends MemberVariable {
8486
class BitField extends Field {
8587
BitField() { bitfield(underlyingElement(this), _, _) }
8688

89+
override string getCanonicalQLClass() { result = "BitField" }
90+
8791
/**
8892
* Gets the size of this bitfield in bits (on the machine where facts
8993
* were extracted).

cpp/ql/src/semmle/code/cpp/Variable.qll

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ private import semmle.code.cpp.internal.ResolveClass
2828
* can have multiple declarations.
2929
*/
3030
class Variable extends Declaration, @variable {
31+
override string getCanonicalQLClass() { result = "Variable" }
32+
3133
/** Gets the initializer of this variable, if any. */
3234
Initializer getInitializer() { result.getDeclaration() = this }
3335

@@ -351,6 +353,8 @@ class StackVariable extends LocalScopeVariable {
351353
* A local variable can be declared by a `DeclStmt` or a `ConditionDeclExpr`.
352354
*/
353355
class LocalVariable extends LocalScopeVariable, @localvariable {
356+
override string getCanonicalQLClass() { result = "LocalVariable" }
357+
354358
override string getName() { localvariables(underlyingElement(this), _, result) }
355359

356360
override Type getType() { localvariables(underlyingElement(this), unresolveElement(result), _) }
@@ -362,6 +366,49 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
362366
}
363367
}
364368

369+
/**
370+
* A variable whose contents always have static storage duration. This can be a
371+
* global variable, a namespace variable, a static local variable, or a static
372+
* member variable.
373+
*/
374+
class StaticStorageDurationVariable extends Variable {
375+
StaticStorageDurationVariable() {
376+
this instanceof GlobalOrNamespaceVariable
377+
or
378+
this.(LocalVariable).isStatic()
379+
or
380+
this.(MemberVariable).isStatic()
381+
}
382+
383+
/**
384+
* Holds if the initializer for this variable is evaluated at compile time.
385+
*/
386+
predicate hasConstantInitialization() {
387+
not runtimeExprInStaticInitializer(this.getInitializer().getExpr())
388+
}
389+
}
390+
391+
/**
392+
* Holds if `e` is an expression in a static initializer that must be evaluated
393+
* at run time. This predicate computes "is non-const" instead of "is const"
394+
* since computing "is const" for an aggregate literal with many children would
395+
* either involve recursion through `forall` on those children or an iteration
396+
* through the rank numbers of the children, both of which can be slow.
397+
*/
398+
private predicate runtimeExprInStaticInitializer(Expr e) {
399+
inStaticInitializer(e) and
400+
if e instanceof AggregateLiteral
401+
then runtimeExprInStaticInitializer(e.getAChild())
402+
else not e.getFullyConverted().isConstant()
403+
}
404+
405+
/** Holds if `e` is part of the initializer of a `StaticStorageDurationVariable`. */
406+
private predicate inStaticInitializer(Expr e) {
407+
exists(StaticStorageDurationVariable var | e = var.getInitializer().getExpr())
408+
or
409+
inStaticInitializer(e.getParent())
410+
}
411+
365412
/**
366413
* A C/C++ variable which has global scope or namespace scope. For example the
367414
* variables `a` and `b` in the following code:
@@ -396,6 +443,8 @@ class NamespaceVariable extends GlobalOrNamespaceVariable {
396443
NamespaceVariable() {
397444
exists(Namespace n | namespacembrs(unresolveElement(n), underlyingElement(this)))
398445
}
446+
447+
override string getCanonicalQLClass() { result = "NamespaceVariable" }
399448
}
400449

401450
/**
@@ -415,6 +464,8 @@ class NamespaceVariable extends GlobalOrNamespaceVariable {
415464
*/
416465
class GlobalVariable extends GlobalOrNamespaceVariable {
417466
GlobalVariable() { not this instanceof NamespaceVariable }
467+
468+
override string getCanonicalQLClass() { result = "GlobalVariable" }
418469
}
419470

420471
/**
@@ -434,6 +485,8 @@ class GlobalVariable extends GlobalOrNamespaceVariable {
434485
class MemberVariable extends Variable, @membervariable {
435486
MemberVariable() { this.isMember() }
436487

488+
override string getCanonicalQLClass() { result = "MemberVariable" }
489+
437490
/** Holds if this member is private. */
438491
predicate isPrivate() { this.hasSpecifier("private") }
439492

0 commit comments

Comments
 (0)