Compare commits

..

11 Commits

Author SHA1 Message Date
Chris Smowton
e27d8c1672 Amend extractor information expectation 2025-01-23 15:36:37 -05:00
Chris Smowton
660922fe4d Don't expect logged properties files in source archives 2025-01-23 15:36:27 -05:00
Paolo Tranquilli
91132b94a9 Swift: drop indisciminate printing of the env 2025-01-23 14:45:47 -05:00
Chris Smowton
02069b63ba Merge pull request #18549 from github/release-prep/2.20.2
Release preparation for version 2.20.2
2025-01-21 12:59:07 +00:00
Chris Smowton
ffa4e3b6d8 Fix changelog typos 2025-01-21 12:51:15 +00:00
github-actions[bot]
ec70b80a0a Release preparation for version 2.20.2 2025-01-21 12:47:53 +00:00
Chris Smowton
32fb6c4660 Merge pull request #18548 from github/revert-18539-release-prep/2.20.2
Revert "Release preparation for version 2.20.2"
2025-01-21 12:05:49 +00:00
Chris Smowton
90c396b46a Revert "Release preparation for version 2.20.2" 2025-01-21 12:02:52 +00:00
Chris Smowton
f1014abee6 Merge pull request #18539 from github/release-prep/2.20.2
Release preparation for version 2.20.2
2025-01-20 14:48:38 +00:00
Chris Smowton
7aab08810e Fix change-note typo 2025-01-20 14:47:40 +00:00
github-actions[bot]
ec1ca5dc25 Release preparation for version 2.20.2 2025-01-20 14:44:12 +00:00
210 changed files with 778 additions and 17488 deletions

View File

@@ -218,7 +218,6 @@ use_repo(
"kotlin-compiler-2.0.0-RC1",
"kotlin-compiler-2.0.20-Beta2",
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-embeddable-1.5.0",
"kotlin-compiler-embeddable-1.5.10",
"kotlin-compiler-embeddable-1.5.20",
@@ -233,7 +232,6 @@ use_repo(
"kotlin-compiler-embeddable-2.0.0-RC1",
"kotlin-compiler-embeddable-2.0.20-Beta2",
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-stdlib-1.5.0",
"kotlin-stdlib-1.5.10",
"kotlin-stdlib-1.5.20",
@@ -248,7 +246,6 @@ use_repo(
"kotlin-stdlib-2.0.0-RC1",
"kotlin-stdlib-2.0.20-Beta2",
"kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-Beta1",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.2-dev
version: 0.4.1
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.4.2-dev
version: 0.4.1
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -1,21 +0,0 @@
class PreprocessorDirective extends @preprocdirect {
string toString() { none() }
}
class Location extends @location_default {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) {
if kind = 14
then result = 6 // Represent MSFT #import as #include
else
if kind = 15 or kind = 6
then result = 3 // Represent #elifdef and #elifndef as #elif
else result = kind
}
from PreprocessorDirective ppd, int kind, Location l
where preprocdirects(ppd, kind, l)
select ppd, getKind(kind), l

View File

@@ -1,3 +0,0 @@
description: Support #elifdef, #elifndef and #import
compatibility: full
preprocdirects.rel: run preprocdirects.qlo

View File

@@ -1,5 +0,0 @@
---
category: feature
---
* New classes `PreprocessorElifdef` and `PreprocessorElifndef` were introduced, which represents the C23/C++23 `#elifdef` and `#elifndef` preprocessor directives.
* A new class `TypeLibraryImport` was introduced, which represents the `#import` preprocessor directive as used by the Microsoft Visual C++ for importing type libraries.

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 3.2.1-dev
version: 3.2.0
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -57,9 +57,9 @@ class IncludeNext extends Include, @ppd_include_next {
}
/**
* An Objective C `#import` preprocessor directive (supported by GCC as
* an extension in C). For example the following code contains one `Import`
* directive:
* A `#import` preprocessor directive (used heavily in Objective C, and
* supported by GCC as an extension in C). For example the following code
* contains one `Import` directive:
* ```
* #import <header3.h>
* ```
@@ -67,14 +67,3 @@ class IncludeNext extends Include, @ppd_include_next {
class Import extends Include, @ppd_objc_import {
override string toString() { result = "#import " + this.getIncludeText() }
}
/**
* A Microsoft `#import` preprocessor directive for importing a type library.
* For example the following code contains one `TypeLibraryImport` directive:
* ```
* #import "library.tlb"
* ```
*/
class TypeLibraryImport extends Include, @ppd_ms_import {
override string toString() { result = "#import " + this.getIncludeText() }
}

View File

@@ -42,7 +42,7 @@ private class TPreprocessorBranchDirective = @ppd_branch or @ppd_else or @ppd_en
/**
* A C/C++ preprocessor branch related directive: `#if`, `#ifdef`,
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif`.
* `#ifndef`, `#elif`, `#else` or `#endif`.
*/
class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBranchDirective {
/**
@@ -74,8 +74,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the next `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif` matching
* this branching directive.
* Gets the next `#elif`, `#else` or `#endif` matching this branching
* directive.
*
* For example `somePreprocessorBranchDirective.getIf().getNext()` gets
* the second directive in the same construct as
@@ -88,8 +88,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the index of this branching directive within the matching `#if`,
* `#ifdef` or `#ifndef`.
* Gets the index of this branching directive within the matching #if,
* #ifdef or #ifndef.
*/
private int getIndexInBranch(PreprocessorBranch branch) {
this =
@@ -102,8 +102,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`,
* `#elif`, `#elifdef`, or `#elifndef`.
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`, or
* `#elif`.
*
* A branching directive has a condition and that condition may be evaluated
* at compile-time. As a result, the preprocessor will either take the
@@ -151,8 +151,8 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* #endif
* ```
* For the related notion of a directive which causes branching (which
* includes `#if`, plus also `#ifdef`, `#ifndef`, `#elif`, `#elifdef`,
* and `#elifndef`), see `PreprocessorBranch`.
* includes `#if`, plus also `#ifdef`, `#ifndef`, and `#elif`), see
* `PreprocessorBranch`.
*/
class PreprocessorIf extends PreprocessorBranch, @ppd_if {
override string toString() { result = "#if " + this.getHead() }
@@ -222,40 +222,6 @@ class PreprocessorElif extends PreprocessorBranch, @ppd_elif {
override string toString() { result = "#elif " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifdef` directive. For example there is a
* `PreprocessorElifdef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifdef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifdef extends PreprocessorBranch, @ppd_elifdef {
override string toString() { result = "#elifdef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifndef` directive. For example there is a
* `PreprocessorElifndef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifndef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifndef extends PreprocessorBranch, @ppd_elifndef {
override string toString() { result = "#elifndef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#endif` directive. For example there is a
* `PreprocessorEndif` on the third line of the following code:

View File

@@ -1,9 +1,8 @@
/**
* This library offers a view of preprocessor branches (`#if`, `#ifdef`,
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, and `#else`) as blocks of
* code between the opening and closing directives, with navigable
* parent-child relationships to other blocks. The main class is
* `PreprocessorBlock`.
* `#ifndef`, `#elif` and `#else`) as blocks of code between the opening and
* closing directives, with navigable parent-child relationships to other
* blocks. The main class is `PreprocessorBlock`.
*/
import cpp
@@ -33,10 +32,10 @@ private int getPreprocIndex(PreprocessorBranchDirective directive) {
/**
* A chunk of code from one preprocessor branch (`#if`, `#ifdef`,
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, or `#else`) to the
* directive that closes it (`#elif`, `#elifdef`, `#elifndef`, `#else`,
* or `#endif`). The `getParent()` method allows these blocks to be
* navigated as a tree, with the root being the entire file.
* `#ifndef`, `#elif` or `#else`) to the directive that closes it
* (`#elif`, `#else` or `#endif`). The `getParent()` method
* allows these blocks to be navigated as a tree, with the root
* being the entire file.
*/
class PreprocessorBlock extends @element {
PreprocessorBlock() {

View File

@@ -2318,15 +2318,12 @@ case @preprocdirect.kind of
| 11 = @ppd_pragma
| 12 = @ppd_objc_import
| 13 = @ppd_include_next
| 14 = @ppd_ms_import
| 15 = @ppd_elifdef
| 16 = @ppd_elifndef
| 18 = @ppd_warning
;
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
preprocpair(
int begin : @ppd_branch ref,

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
description: Support #elifdef, #elifndef and #import
compatibility: partial

View File

@@ -177,12 +177,6 @@ predicate overflows(MulExpr me, Type t) {
)
}
predicate buildModeNoneIntLongConversion(IntType argType, LongType resultType) {
exists(argType) and
exists(resultType) and
exists(Compilation c | c.buildModeNone())
}
from MulExpr me, Type t1, Type t2
where
t1 = me.getType().getUnderlyingType() and
@@ -224,10 +218,7 @@ where
// only report if we cannot prove that the result of the
// multiplication will be less (resp. greater) than the
// maximum (resp. minimum) number we can compute.
overflows(me, t1) and
// In build mode none, many conversions from integer to long are caused by incorrect types,
// so exclude those results
not buildModeNoneIntLongConversion(t1, t2)
overflows(me, t1)
select me,
"Multiplication result may overflow '" + me.getType().toString() + "' before it is converted to '"
+ me.getFullyConverted().getType().toString() + "'."

View File

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

View File

@@ -1,16 +1,10 @@
| #elif defined GREEN | preprocblock.cpp:10:0:11:0 | #ifndef BLUE |
| #elif defined GREEN | preprocblock.cpp:14:0:15:0 | #if 0 |
| #elif defined GREEN | preprocblock.cpp:16:0:17:0 | #else |
| #elifdef GREEN | preprocblock23.cpp:11:0:12:0 | #if 0 |
| #elifdef GREEN | preprocblock23.cpp:13:0:14:0 | #elifndef BLUE |
| (no parent) | file://:0:0:0:0 | |
| (no parent) | header.h:0:0:8:0 | header.h |
| (no parent) | preprocblock23.cpp:0:0:22:0 | preprocblock23.cpp |
| (no parent) | preprocblock.cpp:0:0:25:0 | preprocblock.cpp |
| header.h | header.h:3:0:7:0 | #ifndef HEADER_H |
| preprocblock23.cpp | preprocblock23.cpp:7:0:7:0 | #ifdef RED |
| preprocblock23.cpp | preprocblock23.cpp:8:0:17:0 | #elifdef GREEN |
| preprocblock23.cpp | preprocblock23.cpp:18:0:21:0 | #else |
| preprocblock.cpp | preprocblock.cpp:6:0:6:0 | #ifdef RED |
| preprocblock.cpp | preprocblock.cpp:7:0:20:0 | #elif defined GREEN |
| preprocblock.cpp | preprocblock.cpp:21:0:24:0 | #else |

View File

@@ -1,22 +0,0 @@
// preprocblock23.cpp
// semmle-extractor-options: -std=c++23
#include "header.h"
#define GREEN
#ifdef RED
#elifdef GREEN
#include "header.h"
#if 0
#include "header.h" // not reached
#elifndef BLUE
#include "header.h"
#endif
#include "header.h"
#else
// ...
#endif

View File

@@ -1,7 +1,3 @@
| preprocblock23.cpp:4:1:4:19 | #include "header.h" | preprocblock23.cpp:0:0:22:0 | preprocblock23.cpp |
| preprocblock23.cpp:9:2:9:20 | #include "header.h" | preprocblock23.cpp:8:0:17:0 | #elifdef GREEN |
| preprocblock23.cpp:14:3:14:21 | #include "header.h" | preprocblock23.cpp:13:0:14:0 | #elifndef BLUE |
| preprocblock23.cpp:17:2:17:20 | #include "header.h" | preprocblock23.cpp:8:0:17:0 | #elifdef GREEN |
| preprocblock.cpp:3:1:3:19 | #include "header.h" | preprocblock.cpp:0:0:25:0 | preprocblock.cpp |
| preprocblock.cpp:8:2:8:20 | #include "header.h" | preprocblock.cpp:7:0:20:0 | #elif defined GREEN |
| preprocblock.cpp:11:3:11:21 | #include "header.h" | preprocblock.cpp:10:0:11:0 | #ifndef BLUE |

View File

@@ -1,15 +0,0 @@
// semmle-extractor-options: -std=c++23
#define BAR
#ifdef FOO
#warning C++23 1
#elifdef BAR
#warning C++23 2
#endif
#ifdef FOO
#warning C++23 3
#elifndef FOO
#warning C++23 3
#endif

View File

@@ -1,3 +0,0 @@
// semmle-extractor-options: --microsoft
#import "test.tlb"

View File

@@ -1,13 +1,4 @@
| a.h:0:0:0:0 | a.h | 1 | 1 | 1 | 19 | IncludeNext | "a.h" | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 3 | 1 | 3 | 11 | Macro | BAR | |
| pp23.cpp:0:0:0:0 | pp23.cpp | 5 | 1 | 5 | 10 | PreprocessorIfdef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | PreprocessorElifdef | BAR | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 8 | 1 | 8 | 16 | PreprocessorWarning | C++23 2 | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 11 | 1 | 11 | 10 | PreprocessorIfdef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | PreprocessorElifndef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 14 | 1 | 14 | 16 | PreprocessorWarning | C++23 3 | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 15 | 1 | 15 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 1 | 1 | 1 | 16 | PreprocessorIf | defined(FOO) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 3 | 1 | 3 | 19 | PreprocessorElif | !defined(BAR) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 4 | 1 | 4 | 11 | Macro | BAR | |
@@ -49,6 +40,3 @@
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |
| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | PreprocessorUndef | MULTILINE | N/A |
| pp.h:0:0:0:0 | pp.h | 16 | 1 | 17 | 8 | Include | "pp.h" | N/A |
| ppms.cpp:0:0:0:0 | ppms.cpp | 3 | 1 | 3 | 18 | TypeLibraryImport | "test.tlb" | N/A |
| test.tlh:0:0:0:0 | test.tlh | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
| test.tlh:0:0:0:0 | test.tlh | 3 | 1 | 3 | 21 | PreprocessorWarning | type library | N/A |

View File

@@ -1,3 +0,0 @@
#pragma once
#warning type library

View File

@@ -1,10 +0,0 @@
// semmle-extractor-options: --build-mode none
int f();
void test() {
int i = f();
unsigned u = i;
long j = i * i; // GOOD: build mode none
unsigned long k = u * u; // GOOD: build mode none
}

View File

@@ -1 +0,0 @@
Likely Bugs/Arithmetic/IntMultToLong.ql

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 4.0.3-dev
version: 4.0.2
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* All *experimental* queries have been deprecated. The queries are instead available as part of the *default* query suite in [CodeQL-Community-Packs](https://github.com/GitHubSecurityLab/CodeQL-Community-Packs).

View File

@@ -15,16 +15,10 @@
*/
import csharp
deprecated import TaintedWebClientLib
deprecated import TaintedWebClient::PathGraph
import TaintedWebClientLib
import TaintedWebClient::PathGraph
deprecated query predicate problems(
DataFlow::Node sinkNode, TaintedWebClient::PathNode source, TaintedWebClient::PathNode sink,
string message1, DataFlow::Node sourceNode, string message2
) {
TaintedWebClient::flowPath(source, sink) and
sinkNode = sink.getNode() and
message1 = "A method of WebClient depepends on a $@." and
sourceNode = source.getNode() and
message2 = "user-provided value"
}
from TaintedWebClient::PathNode source, TaintedWebClient::PathNode sink
where TaintedWebClient::flowPath(source, sink)
select sink.getNode(), source, sink, "A method of WebClient depepends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,5 +1,3 @@
deprecated module;
import csharp
import semmle.code.csharp.frameworks.system.Net
import semmle.code.csharp.frameworks.System

View File

@@ -11,16 +11,10 @@
*/
import csharp
deprecated import RequestForgery::RequestForgery
deprecated import RequestForgeryFlow::PathGraph
import RequestForgery::RequestForgery
import RequestForgeryFlow::PathGraph
deprecated query predicate problems(
DataFlow::Node sinkNode, RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink,
string message1, DataFlow::Node sourceNode, string message2
) {
RequestForgeryFlow::flowPath(source, sink) and
sinkNode = sink.getNode() and
message1 = "The URL of this request depends on a $@." and
sourceNode = source.getNode() and
message2 = "user-provided value"
}
from RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink
where RequestForgeryFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "The URL of this request depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,5 +1,3 @@
deprecated module;
import csharp
module RequestForgery {

View File

@@ -17,91 +17,89 @@ import csharp
import semmle.code.asp.WebConfig
import semmle.code.csharp.frameworks.system.Web
import semmle.code.csharp.frameworks.microsoft.AspNetCore
deprecated import experimental.dataflow.flowsources.AuthCookie
import experimental.dataflow.flowsources.AuthCookie
deprecated query predicate problems(Expr httpOnlySink, string message) {
(
exists(Assignment a, Expr val |
httpOnlySink = a.getRValue() and
val.getValue() = "false" and
(
exists(ObjectCreation oc |
getAValueForProp(oc, a, "HttpOnly") = val and
(
oc.getType() instanceof SystemWebHttpCookie and
isCookieWithSensitiveName(oc.getArgument(0))
or
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
iResponse.getAppendMethod() = mc.getTarget() and
isCookieWithSensitiveName(mc.getArgument(0)) and
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
// Passed as third argument to `IResponseCookies.Append`
exists(DataFlow::Node creation, DataFlow::Node append |
CookieOptionsTracking::flow(creation, append) and
creation.asExpr() = oc and
append.asExpr() = mc.getArgument(2)
)
)
)
)
or
exists(PropertyWrite pw |
(
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
pw.getProperty().getDeclaringType() instanceof
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
) and
pw.getProperty().getName() = "HttpOnly" and
a.getLValue() = pw and
DataFlow::localExprFlow(val, a.getRValue())
)
)
)
or
exists(Call c |
httpOnlySink = c and
(
exists(MicrosoftAspNetCoreHttpResponseCookies iResponse, MethodCall mc |
// default is not configured or is not set to `Always`
not getAValueForCookiePolicyProp("HttpOnly").getValue() = "1" and
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
iResponse.getAppendMethod() = mc.getTarget() and
isCookieWithSensitiveName(mc.getArgument(0)) and
(
// `HttpOnly` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
not isPropertySet(oc, "HttpOnly") and
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
)
or
// IResponseCookies.Append(String, String) was called, `HttpOnly` is set to `false` by default
mc = c and
mc.getNumberOfArguments() < 3
)
)
or
exists(ObjectCreation oc |
oc = c and
from Expr httpOnlySink
where
exists(Assignment a, Expr val |
httpOnlySink = a.getRValue() and
val.getValue() = "false" and
(
exists(ObjectCreation oc |
getAValueForProp(oc, a, "HttpOnly") = val and
(
oc.getType() instanceof SystemWebHttpCookie and
isCookieWithSensitiveName(oc.getArgument(0)) and
// the property wasn't explicitly set, so a default value from config is used
not isPropertySet(oc, "HttpOnly") and
// the default in config is not set to `true`
not exists(XmlElement element |
element instanceof HttpCookiesElement and
element.(HttpCookiesElement).isHttpOnlyCookies()
isCookieWithSensitiveName(oc.getArgument(0))
or
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
iResponse.getAppendMethod() = mc.getTarget() and
isCookieWithSensitiveName(mc.getArgument(0)) and
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
// Passed as third argument to `IResponseCookies.Append`
exists(DataFlow::Node creation, DataFlow::Node append |
CookieOptionsTracking::flow(creation, append) and
creation.asExpr() = oc and
append.asExpr() = mc.getArgument(2)
)
)
)
)
or
exists(PropertyWrite pw |
(
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
pw.getProperty().getDeclaringType() instanceof
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
) and
pw.getProperty().getName() = "HttpOnly" and
a.getLValue() = pw and
DataFlow::localExprFlow(val, a.getRValue())
)
)
) and
message = "Cookie attribute 'HttpOnly' is not set to true."
}
)
or
exists(Call c |
httpOnlySink = c and
(
exists(MicrosoftAspNetCoreHttpResponseCookies iResponse, MethodCall mc |
// default is not configured or is not set to `Always`
not getAValueForCookiePolicyProp("HttpOnly").getValue() = "1" and
// there is no callback `OnAppendCookie` that sets `HttpOnly` to true
not OnAppendCookieHttpOnlyTracking::flowTo(_) and
iResponse.getAppendMethod() = mc.getTarget() and
isCookieWithSensitiveName(mc.getArgument(0)) and
(
// `HttpOnly` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
not isPropertySet(oc, "HttpOnly") and
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
)
or
// IResponseCookies.Append(String, String) was called, `HttpOnly` is set to `false` by default
mc = c and
mc.getNumberOfArguments() < 3
)
)
or
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof SystemWebHttpCookie and
isCookieWithSensitiveName(oc.getArgument(0)) and
// the property wasn't explicitly set, so a default value from config is used
not isPropertySet(oc, "HttpOnly") and
// the default in config is not set to `true`
not exists(XmlElement element |
element instanceof HttpCookiesElement and
element.(HttpCookiesElement).isHttpOnlyCookies()
)
)
)
)
select httpOnlySink, "Cookie attribute 'HttpOnly' is not set to true."

View File

@@ -68,14 +68,15 @@ predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) {
)
}
deprecated query predicate problems(Expr e, string message) {
exists(Class c, Assembly asm | asm = c.getLocation() |
from Expr e, Class c, Assembly asm
where
asm = c.getLocation() and
(
exists(Expr e2 |
isCreatingAzureClientSideEncryptionObject(e, c, e2) and
not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm)
)
or
isCreatingOutdatedAzureClientSideEncryptionObject(e, c)
) and
message = "Unsafe usage of v1 version of Azure Storage client-side encryption."
}
)
select e, "Unsafe usage of v1 version of Azure Storage client-side encryption."

View File

@@ -17,91 +17,89 @@ import csharp
import semmle.code.asp.WebConfig
import semmle.code.csharp.frameworks.system.Web
import semmle.code.csharp.frameworks.microsoft.AspNetCore
deprecated import experimental.dataflow.flowsources.AuthCookie
import experimental.dataflow.flowsources.AuthCookie
deprecated query predicate problems(Expr secureSink, string message) {
(
exists(Call c |
secureSink = c and
from Expr secureSink
where
exists(Call c |
secureSink = c and
(
// default is not configured or is not set to `Always` or `SameAsRequest`
not (
getAValueForCookiePolicyProp("Secure").getValue() = "0" or
getAValueForCookiePolicyProp("Secure").getValue() = "1"
) and
// there is no callback `OnAppendCookie` that sets `Secure` to true
not OnAppendCookieSecureTracking::flowTo(_) and
(
// default is not configured or is not set to `Always` or `SameAsRequest`
not (
getAValueForCookiePolicyProp("Secure").getValue() = "0" or
getAValueForCookiePolicyProp("Secure").getValue() = "1"
) and
// there is no callback `OnAppendCookie` that sets `Secure` to true
not OnAppendCookieSecureTracking::flowTo(_) and
(
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
not isPropertySet(oc, "Secure") and
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
)
or
// IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
mc = c and
iResponse.getAppendMethod() = mc.getTarget() and
mc.getNumberOfArguments() < 3
)
)
or
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof SystemWebHttpCookie and
// the property wasn't explicitly set, so a default value from config is used
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
not isPropertySet(oc, "Secure") and
// the default in config is not set to `true`
// the `exists` below covers the `cs/web/requiressl-not-set`
not exists(XmlElement element |
element instanceof FormsElement and
element.(FormsElement).isRequireSsl()
or
element instanceof HttpCookiesElement and
element.(HttpCookiesElement).isRequireSsl()
)
)
)
)
or
exists(Assignment a, Expr val |
secureSink = a.getRValue() and
(
exists(ObjectCreation oc |
getAValueForProp(oc, a, "Secure") = val and
val.getValue() = "false" and
(
oc.getType() instanceof SystemWebHttpCookie
or
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
// there is no callback `OnAppendCookie` that sets `Secure` to true
not OnAppendCookieSecureTracking::flowTo(_) and
// the cookie option is passed to `Append`
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
)
or
exists(PropertyWrite pw |
(
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
pw.getProperty().getDeclaringType() instanceof
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
) and
pw.getProperty().getName() = "SecurePolicy" and
a.getLValue() = pw and
DataFlow::localExprFlow(val, a.getRValue()) and
val.getValue() = "2" // None
// IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default
exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse |
mc = c and
iResponse.getAppendMethod() = mc.getTarget() and
mc.getNumberOfArguments() < 3
)
)
or
exists(ObjectCreation oc |
oc = c and
oc.getType() instanceof SystemWebHttpCookie and
// the property wasn't explicitly set, so a default value from config is used
not isPropertySet(oc, "Secure") and
// the default in config is not set to `true`
// the `exists` below covers the `cs/web/requiressl-not-set`
not exists(XmlElement element |
element instanceof FormsElement and
element.(FormsElement).isRequireSsl()
or
element instanceof HttpCookiesElement and
element.(HttpCookiesElement).isRequireSsl()
)
)
)
) and
message = "Cookie attribute 'Secure' is not set to true."
}
)
or
exists(Assignment a, Expr val |
secureSink = a.getRValue() and
(
exists(ObjectCreation oc |
getAValueForProp(oc, a, "Secure") = val and
val.getValue() = "false" and
(
oc.getType() instanceof SystemWebHttpCookie
or
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
// there is no callback `OnAppendCookie` that sets `Secure` to true
not OnAppendCookieSecureTracking::flowTo(_) and
// the cookie option is passed to `Append`
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
)
)
or
exists(PropertyWrite pw |
(
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or
pw.getProperty().getDeclaringType() instanceof
MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions
) and
pw.getProperty().getName() = "SecurePolicy" and
a.getLValue() = pw and
DataFlow::localExprFlow(val, a.getRValue()) and
val.getValue() = "2" // None
)
)
)
select secureSink, "Cookie attribute 'Secure' is not set to true."

View File

@@ -192,13 +192,7 @@ module HashWithoutSaltConfig implements DataFlow::ConfigSig {
module HashWithoutSalt = TaintTracking::Global<HashWithoutSaltConfig>;
deprecated query predicate problems(
DataFlow::Node sinkNode, HashWithoutSalt::PathNode source, HashWithoutSalt::PathNode sink,
string message, DataFlow::Node sourceNode, string password
) {
sinkNode = sink.getNode() and
sourceNode = source.getNode() and
HashWithoutSalt::flowPath(source, sink) and
message = "$@ is hashed without a salt." and
password = "The password"
}
from HashWithoutSalt::PathNode source, HashWithoutSalt::PathNode sink
where HashWithoutSalt::flowPath(source, sink)
select sink.getNode(), source, sink, "$@ is hashed without a salt.", source.getNode(),
"The password"

View File

@@ -1,5 +1,3 @@
deprecated module;
import csharp
import DataFlow

View File

@@ -14,17 +14,11 @@
import csharp
import DataFlow
deprecated import JsonWebTokenHandlerLib
import JsonWebTokenHandlerLib
import semmle.code.csharp.commons.QualifiedName
deprecated query predicate problems(
CallableAlwaysReturnsTrue e, string message, TokenValidationParametersProperty p,
string fullyQualifiedName
) {
exists(string qualifier, string name | p.hasFullyQualifiedName(qualifier, name) |
fullyQualifiedName = getQualifiedName(qualifier, name)
) and
e = p.getAnAssignedValue() and
message =
"JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\"."
}
from TokenValidationParametersProperty p, CallableAlwaysReturnsTrue e, string qualifier, string name
where e = p.getAnAssignedValue() and p.hasFullyQualifiedName(qualifier, name)
select e,
"JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\".",
p, getQualifiedName(qualifier, name)

View File

@@ -12,18 +12,15 @@
*/
import csharp
deprecated import JsonWebTokenHandlerLib
import JsonWebTokenHandlerLib
import semmle.code.csharp.commons.QualifiedName
deprecated query predicate problems(
DataFlow::Node sink, string message, TokenValidationParametersPropertySensitiveValidation pw,
string fullyQualifiedName, DataFlow::Node source, string value
) {
from
DataFlow::Node source, DataFlow::Node sink,
TokenValidationParametersPropertySensitiveValidation pw, string qualifier, string name
where
FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation::flow(source, sink) and
sink.asExpr() = pw.getAnAssignedValue() and
exists(string qualifier, string name | pw.hasFullyQualifiedName(qualifier, name) |
fullyQualifiedName = getQualifiedName(qualifier, name)
) and
message = "The security sensitive property $@ is being disabled by the following value: $@." and
value = "false"
}
pw.hasFullyQualifiedName(qualifier, name)
select sink, "The security sensitive property $@ is being disabled by the following value: $@.", pw,
getQualifiedName(qualifier, name), source, "false"

View File

@@ -3,7 +3,6 @@
*
* Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.
*/
deprecated module;
import csharp

View File

@@ -9,10 +9,9 @@
*/
import csharp
deprecated import DataSetSerialization
import DataSetSerialization
deprecated query predicate problems(DataSetOrTableRelatedClass dstc, string message) {
dstc.fromSource() and
message =
"Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."
}
from DataSetOrTableRelatedClass dstc
where dstc.fromSource()
select dstc,
"Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."

View File

@@ -10,17 +10,12 @@
*/
import csharp
deprecated import DataSetSerialization
import DataSetSerialization
deprecated query predicate problems(
Member m, string message, UnsafeXmlSerializerImplementation c, string classMessage, Member member,
string memberMessage
) {
from UnsafeXmlSerializerImplementation c, Member m
where
c.fromSource() and
isClassUnsafeXmlSerializerImplementation(c, m) and
message =
"Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." and
classMessage = c.toString() and
member = m and
memberMessage = m.toString()
}
isClassUnsafeXmlSerializerImplementation(c, m)
select m,
"Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.",
c, c.toString(), m, m.toString()

View File

@@ -10,7 +10,7 @@
*/
import csharp
deprecated import DataSetSerialization
import DataSetSerialization
predicate xmlSerializerConstructorArgument(Expr e) {
exists(ObjectCreation oc, Constructor c | e = oc.getArgument(0) |
@@ -21,7 +21,7 @@ predicate xmlSerializerConstructorArgument(Expr e) {
)
}
deprecated predicate unsafeDataContractTypeCreation(Expr e) {
predicate unsafeDataContractTypeCreation(Expr e) {
exists(MethodCall gt |
gt.getTarget().getName() = "GetType" and
e = gt and
@@ -31,20 +31,16 @@ deprecated predicate unsafeDataContractTypeCreation(Expr e) {
e.(TypeofExpr).getTypeAccess().getTarget() instanceof DataSetOrTableRelatedClass
}
deprecated module FlowToDataSerializerConstructorConfig implements DataFlow::ConfigSig {
module FlowToDataSerializerConstructorConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { unsafeDataContractTypeCreation(node.asExpr()) }
predicate isSink(DataFlow::Node node) { xmlSerializerConstructorArgument(node.asExpr()) }
}
deprecated module FlowToDataSerializerConstructor =
DataFlow::Global<FlowToDataSerializerConstructorConfig>;
module FlowToDataSerializerConstructor = DataFlow::Global<FlowToDataSerializerConstructorConfig>;
deprecated query predicate problems(
DataFlow::Node sink, string message, DataFlow::Node source, string sourceMessage
) {
FlowToDataSerializerConstructor::flow(source, sink) and
message =
"Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source." and
sourceMessage = source.toString()
}
from DataFlow::Node source, DataFlow::Node sink
where FlowToDataSerializerConstructor::flow(source, sink)
select sink,
"Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source.",
source, source.toString()

View File

@@ -10,10 +10,8 @@
*/
import csharp
deprecated import DataSetSerialization
import DataSetSerialization
deprecated query predicate problems(UnsafeXmlReadMethodCall mc, string message) {
message =
"Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." and
exists(mc)
}
from UnsafeXmlReadMethodCall mc
select mc,
"Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."

View File

@@ -48,8 +48,8 @@ predicate isExternMethod(Method externMethod) {
SystemRuntimeInteropServicesComImportAttributeClass
}
deprecated query predicate problems(MethodCall mc, string message) {
from MethodCall mc
where
isExternMethod(mc.getTarget()) and
isDangerousMethod(mc.getTarget()) and
message = "Call to an external method '" + mc.getTarget().getName() + "'."
}
isDangerousMethod(mc.getTarget())
select mc, "Call to an external method '" + mc.getTarget().getName() + "'."

View File

@@ -174,16 +174,13 @@ predicate isPotentialTimeBomb(
)
}
deprecated query predicate problems(
SelectionStmt selStatement, Flow::PathNode source, Flow::PathNode sink, string message,
Call timeComparisonCall, string timeComparisonCallString, Call timeArithmeticCall, string offset,
Call getLastWriteTimeMethodCall, string lastWriteTimeMethodCallMessage
) {
from
Flow::PathNode source, Flow::PathNode sink, Call getLastWriteTimeMethodCall,
Call timeArithmeticCall, Call timeComparisonCall, SelectionStmt selStatement
where
isPotentialTimeBomb(source, sink, getLastWriteTimeMethodCall, timeArithmeticCall,
timeComparisonCall, selStatement) and
message =
"Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger." and
timeComparisonCallString = timeComparisonCall.toString() and
offset = "offset" and
lastWriteTimeMethodCallMessage = "last modification time of a file"
}
timeComparisonCall, selStatement)
select selStatement, source, sink,
"Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger.",
timeComparisonCall, timeComparisonCall.toString(), timeArithmeticCall, "offset",
getLastWriteTimeMethodCall, "last modification time of a file"

View File

@@ -42,15 +42,8 @@ predicate isSuspiciousPropertyName(PropertyRead pr) {
pr.getTarget().hasFullyQualifiedName("System.Diagnostics", "Process", "ProcessName")
}
deprecated query predicate problems(
DataFlow::Node srcNode, DataFlowFromMethodToHash::PathNode src,
DataFlowFromMethodToHash::PathNode sink, string message, DataFlow::Node sinkNode,
string sinkMessage
) {
srcNode = src.getNode() and
sinkNode = sink.getNode() and
DataFlowFromMethodToHash::flow(srcNode, sinkNode) and
message =
"The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent." and
sinkMessage = "this process name"
}
from DataFlowFromMethodToHash::PathNode src, DataFlowFromMethodToHash::PathNode sink
where DataFlowFromMethodToHash::flow(src.getNode(), sink.getNode())
select src.getNode(), src, sink,
"The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent.",
sink.getNode(), "this process name"

View File

@@ -1,7 +1,6 @@
/**
* Provides classes and predicates for detecting insecure cookies.
*/
deprecated module;
import csharp
import semmle.code.csharp.frameworks.microsoft.AspNetCore

View File

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

View File

@@ -4,5 +4,5 @@ nodes
| RequestForgery.cs:12:52:12:54 | url : String | semmle.label | url : String |
| RequestForgery.cs:14:66:14:68 | access to parameter url | semmle.label | access to parameter url |
subpaths
problems
#select
| RequestForgery.cs:14:66:14:68 | access to parameter url | RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:12:52:12:54 | url | user-provided value |

View File

@@ -1,3 +1,7 @@
#select
| HashWithoutSalt.cs:20:49:20:56 | access to local variable passBuff | HashWithoutSalt.cs:18:70:18:77 | access to parameter password : String | HashWithoutSalt.cs:20:49:20:56 | access to local variable passBuff | $@ is hashed without a salt. | HashWithoutSalt.cs:18:70:18:77 | access to parameter password | The password |
| HashWithoutSalt.cs:39:51:39:59 | access to local variable passBytes | HashWithoutSalt.cs:38:64:38:71 | access to parameter password : String | HashWithoutSalt.cs:39:51:39:59 | access to local variable passBytes | $@ is hashed without a salt. | HashWithoutSalt.cs:38:64:38:71 | access to parameter password | The password |
| HashWithoutSalt.cs:71:48:71:56 | access to local variable passBytes | HashWithoutSalt.cs:70:64:70:71 | access to parameter password : String | HashWithoutSalt.cs:71:48:71:56 | access to local variable passBytes | $@ is hashed without a salt. | HashWithoutSalt.cs:70:64:70:71 | access to parameter password | The password |
edges
| HashWithoutSalt.cs:18:17:18:24 | access to local variable passBuff : IBuffer | HashWithoutSalt.cs:20:49:20:56 | access to local variable passBuff | provenance | |
| HashWithoutSalt.cs:18:28:18:105 | call to method ConvertStringToBinary : IBuffer | HashWithoutSalt.cs:18:17:18:24 | access to local variable passBuff : IBuffer | provenance | |
@@ -23,8 +27,4 @@ nodes
| HashWithoutSalt.cs:70:28:70:72 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| HashWithoutSalt.cs:70:64:70:71 | access to parameter password : String | semmle.label | access to parameter password : String |
| HashWithoutSalt.cs:71:48:71:56 | access to local variable passBytes | semmle.label | access to local variable passBytes |
problems
| HashWithoutSalt.cs:20:49:20:56 | access to local variable passBuff | HashWithoutSalt.cs:18:70:18:77 | access to parameter password : String | HashWithoutSalt.cs:20:49:20:56 | access to local variable passBuff | $@ is hashed without a salt. | HashWithoutSalt.cs:18:70:18:77 | access to parameter password | The password |
| HashWithoutSalt.cs:39:51:39:59 | access to local variable passBytes | HashWithoutSalt.cs:38:64:38:71 | access to parameter password : String | HashWithoutSalt.cs:39:51:39:59 | access to local variable passBytes | $@ is hashed without a salt. | HashWithoutSalt.cs:38:64:38:71 | access to parameter password | The password |
| HashWithoutSalt.cs:71:48:71:56 | access to local variable passBytes | HashWithoutSalt.cs:70:64:70:71 | access to parameter password : String | HashWithoutSalt.cs:71:48:71:56 | access to local variable passBytes | $@ is hashed without a salt. | HashWithoutSalt.cs:70:64:70:71 | access to parameter password | The password |
subpaths

View File

@@ -17,7 +17,7 @@ edges
| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo | provenance | |
| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo : Int32 | provenance | |
| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:36:71:70 | call to method AddHours | provenance | |
problems
#select
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo : Int32 | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:76 | ... >= ... | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |

View File

@@ -1,4 +1,4 @@
edges
nodes
subpaths
problems
#select

View File

@@ -20,12 +20,12 @@
Java,"Java 7 to 22 [5]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [6]_",``.java``
Kotlin,"Kotlin 1.5.0 to 2.1.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.5.0 to 2.1.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [7]_"
Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [9]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
Swift [10]_,"Swift 5.4-5.10","Swift compiler","``.swift``"
TypeScript [11]_,"2.6-5.7",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
TypeScript [11]_,"2.6-5.6",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
.. container:: footnote-group

View File

@@ -138,5 +138,5 @@ sync,,,34,,,,,,,,,,,,,,,,,,,,,,,34,
syscall,5,2,8,5,,,,,,,,,,,,,,,,,,2,,,,8,
text/scanner,,,3,,,,,,,,,,,,,,,,,,,,,,,3,
text/tabwriter,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
text/template,,,4,,,,,,,,,,,,,,,,,,,,,,,4,
text/template,,,6,,,,,,,,,,,,,,,,,,,,,,,6,
xorm.io/xorm,34,,,,,,,,,,,,,,34,,,,,,,,,,,,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
138 syscall 5 2 8 5 2 8
139 text/scanner 3 3
140 text/tabwriter 1 1
141 text/template 4 6 4 6
142 xorm.io/xorm 34 34

View File

@@ -26,7 +26,7 @@ Go framework & library support
`Macaron <https://gopkg.in/macaron.v1>`_,``gopkg.in/macaron*``,12,1,1
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",52,603,104
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",52,605,104
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
`beego <https://beego.me/>`_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",102,63,213
@@ -61,5 +61,5 @@ Go framework & library support
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Others,"``github.com/Masterminds/squirrel``, ``github.com/caarlos0/env``, ``github.com/go-gorm/gorm``, ``github.com/go-xorm/xorm``, ``github.com/gobuffalo/envy``, ``github.com/gogf/gf/database/gdb``, ``github.com/hashicorp/go-envparse``, ``github.com/jinzhu/gorm``, ``github.com/jmoiron/sqlx``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``, ``github.com/lann/squirrel``, ``github.com/raindog308/gorqlite``, ``github.com/rqlite/gorqlite``, ``github.com/uptrace/bun``, ``go.mongodb.org/mongo-driver/mongo``, ``gopkg.in/Masterminds/squirrel``, ``gorm.io/gorm``, ``xorm.io/xorm``",117,16,391
Totals,,459,941,1532
Totals,,459,943,1532

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries
version: 1.0.16-dev
version: 1.0.15
groups:
- go
- queries

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added the [rs cors](https://github.com/rs/cors) library to the CorsMisconfiguration.ql query

View File

@@ -1,5 +0,0 @@
---
category: minorAnalysis
---
* By implementing `ImplicitFieldReadNode` it is now possible to declare a dataflow node that reads any content (fields, array members, map keys and values). For example, this is appropriate for modelling a serialization method that flattens a potentially deep data structure into a string or byte array.
* The `Template.Execute[Template]` methods of the `text/template` package now correctly convey taint from any nested fields to their result. This may produce more results from any taint-tracking query when the `text/template` package is in use.

View File

@@ -7,5 +7,5 @@ extensions:
- ["text/template", "", False, "HTMLEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["text/template", "", False, "JSEscape", "", "", "Argument[1]", "Argument[0]", "taint", "manual"]
- ["text/template", "", False, "JSEscapeString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
# - ["text/template", "Template", True, "Execute", "", "", "Argument[1]", "Argument[0]", "taint", "manual"] # Implemented in QL to provide an arbitrary content read from the input.
# - ["text/template", "Template", True, "ExecuteTemplate", "", "", "Argument[2]", "Argument[0]", "taint", "manual"] # Implemented in QL to provide an arbitrary content read from the input.
- ["text/template", "Template", True, "Execute", "", "", "Argument[1]", "Argument[0]", "taint", "manual"]
- ["text/template", "Template", True, "ExecuteTemplate", "", "", "Argument[2]", "Argument[0]", "taint", "manual"]

View File

@@ -32,7 +32,6 @@ import semmle.go.frameworks.Afero
import semmle.go.frameworks.AwsLambda
import semmle.go.frameworks.Beego
import semmle.go.frameworks.BeegoOrm
import semmle.go.frameworks.RsCors
import semmle.go.frameworks.Couchbase
import semmle.go.frameworks.Echo
import semmle.go.frameworks.ElazarlGoproxy

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 3.0.3-dev
version: 3.0.2
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -143,28 +143,26 @@ predicate jumpStep(Node n1, Node n2) {
* Thus, `node2` references an object with a content `x` that contains the
* value of `node1`.
*/
predicate storeStep(Node node1, ContentSet cs, Node node2) {
exists(Content c | cs.asOneContent() = c |
// a write `(*p).f = rhs` is modeled as two store steps: `rhs` is flows into field `f` of `(*p)`,
// which in turn flows into the pointer content of `p`
exists(Write w, Field f, DataFlow::Node base, DataFlow::Node rhs | w.writesField(base, f, rhs) |
node1 = rhs and
node2.(PostUpdateNode).getPreUpdateNode() = base and
c = any(DataFlow::FieldContent fc | fc.getField() = f)
or
node1 = base and
node2.(PostUpdateNode).getPreUpdateNode() = node1.(PointerDereferenceNode).getOperand() and
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType())
)
predicate storeStep(Node node1, ContentSet c, Node node2) {
// a write `(*p).f = rhs` is modeled as two store steps: `rhs` is flows into field `f` of `(*p)`,
// which in turn flows into the pointer content of `p`
exists(Write w, Field f, DataFlow::Node base, DataFlow::Node rhs | w.writesField(base, f, rhs) |
node1 = rhs and
node2.(PostUpdateNode).getPreUpdateNode() = base and
c = any(DataFlow::FieldContent fc | fc.getField() = f)
or
node1 = node2.(AddressOperationNode).getOperand() and
node1 = base and
node2.(PostUpdateNode).getPreUpdateNode() = node1.(PointerDereferenceNode).getOperand() and
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType())
or
containerStoreStep(node1, node2, c)
)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), cs,
node1 = node2.(AddressOperationNode).getOperand() and
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType())
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
node2.(FlowSummaryNode).getSummaryNode())
or
containerStoreStep(node1, node2, c)
}
/**
@@ -172,26 +170,20 @@ predicate storeStep(Node node1, ContentSet cs, Node node2) {
* Thus, `node1` references an object with a content `c` whose value ends up in
* `node2`.
*/
predicate readStep(Node node1, ContentSet cs, Node node2) {
exists(Content c | cs.asOneContent() = c |
node1 = node2.(PointerDereferenceNode).getOperand() and
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node1.getType())
or
exists(FieldReadNode read |
node2 = read and
node1 = read.getBase() and
c = any(DataFlow::FieldContent fc | fc.getField() = read.getField())
)
or
containerReadStep(node1, node2, c)
predicate readStep(Node node1, ContentSet c, Node node2) {
node1 = node2.(PointerDereferenceNode).getOperand() and
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node1.getType())
or
exists(FieldReadNode read |
node2 = read and
node1 = read.getBase() and
c = any(DataFlow::FieldContent fc | fc.getField() = read.getField())
)
or
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), cs,
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
node2.(FlowSummaryNode).getSummaryNode())
or
any(ImplicitFieldReadNode ifrn).shouldImplicitlyReadAllFields(node1) and
cs.isUniversalContent() and
node1 = node2
containerReadStep(node1, node2, c)
}
/**

View File

@@ -7,7 +7,6 @@ private import semmle.go.dataflow.FunctionInputsAndOutputs
private import semmle.go.dataflow.ExternalFlow
private import DataFlowPrivate
private import FlowSummaryImpl as FlowSummaryImpl
private import codeql.util.Unit
import DataFlowNodes::Public
/**
@@ -51,18 +50,6 @@ abstract class FunctionModel extends Function {
}
}
/**
* A unit class for adding nodes that should implicitly read from all nested content.
*
* For example, this might be appropriate for the argument to a method that serializes a struct.
*/
class ImplicitFieldReadNode extends Unit {
/**
* Holds if the node `n` should implicitly read from all nested content in a taint-tracking context.
*/
abstract predicate shouldImplicitlyReadAllFields(DataFlow::Node n);
}
/**
* Gets the `Node` corresponding to `insn`.
*/
@@ -182,11 +169,6 @@ class Content extends TContent {
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
/**
* Gets the `ContentSet` contaning only this content.
*/
ContentSet asContentSet() { result.asOneContent() = this }
}
/** A reference through a field. */
@@ -254,33 +236,21 @@ class SyntheticFieldContent extends Content, TSyntheticFieldContent {
override string toString() { result = s.toString() }
}
private newtype TContentSet =
TOneContent(Content c) or
TAllContent()
/**
* An entity that represents a set of `Content`s.
*
* The set may be interpreted differently depending on whether it is
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
*/
class ContentSet instanceof TContentSet {
class ContentSet instanceof Content {
/** Gets a content that may be stored into when storing into this set. */
Content getAStoreContent() { this = TOneContent(result) }
Content getAStoreContent() { result = this }
/** Gets a content that may be read from when reading from this set. */
Content getAReadContent() {
this = TOneContent(result)
or
this = TAllContent() and exists(result)
}
Content getAReadContent() { result = this }
/** Gets a textual representation of this content set. */
string toString() {
exists(Content c | this = TOneContent(c) | result = c.toString())
or
this = TAllContent() and result = "all content"
}
string toString() { result = super.toString() }
/**
* Holds if this element is at the specified location.
@@ -292,27 +262,8 @@ class ContentSet instanceof TContentSet {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(Content c | this = TOneContent(c) |
c.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
)
or
this = TAllContent() and
filepath = "" and
startline = 0 and
startcolumn = 0 and
endline = 0 and
endcolumn = 0
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/**
* If this is a singleton content set, returns the content.
*/
Content asOneContent() { this = TOneContent(result) }
/**
* Holds if this is a universal content set.
*/
predicate isUniversalContent() { this = TAllContent() }
}
/**

View File

@@ -61,28 +61,26 @@ module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
}
string encodeContent(ContentSet cs, string arg) {
exists(Content c | cs.asOneContent() = c |
exists(Field f, string package, string className, string fieldName |
f = c.(FieldContent).getField() and
f.hasQualifiedName(package, className, fieldName) and
result = "Field" and
arg = package + "." + className + "." + fieldName
)
or
exists(SyntheticField f |
f = c.(SyntheticFieldContent).getField() and result = "SyntheticField" and arg = f
)
or
c instanceof ArrayContent and result = "ArrayElement" and arg = ""
or
c instanceof CollectionContent and result = "Element" and arg = ""
or
c instanceof MapKeyContent and result = "MapKey" and arg = ""
or
c instanceof MapValueContent and result = "MapValue" and arg = ""
or
c instanceof PointerContent and result = "Dereference" and arg = ""
exists(Field f, string package, string className, string fieldName |
f = cs.(FieldContent).getField() and
f.hasQualifiedName(package, className, fieldName) and
result = "Field" and
arg = package + "." + className + "." + fieldName
)
or
exists(SyntheticField f |
f = cs.(SyntheticFieldContent).getField() and result = "SyntheticField" and arg = f
)
or
cs instanceof ArrayContent and result = "ArrayElement" and arg = ""
or
cs instanceof CollectionContent and result = "Element" and arg = ""
or
cs instanceof MapKeyContent and result = "MapKey" and arg = ""
or
cs instanceof MapValueContent and result = "MapValue" and arg = ""
or
cs instanceof PointerContent and result = "Dereference" and arg = ""
}
bindingset[token]
@@ -525,9 +523,7 @@ module Private {
SummaryComponent qualifier() { result = argument(-1) }
/** Gets a summary component for field `f`. */
SummaryComponent field(Field f) {
result = content(any(FieldContent c | c.getField() = f).asContentSet())
}
SummaryComponent field(Field f) { result = content(any(FieldContent c | c.getField() = f)) }
/** Gets a summary component that represents the return value of a call. */
SummaryComponent return() { result = SC::return(_) }

View File

@@ -47,11 +47,10 @@ private Type getElementType(Type containerType) {
* of `c` at sinks and inputs to additional taint steps.
*/
bindingset[node]
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet cs) {
exists(Type containerType, DataFlow::Content c |
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) {
exists(Type containerType |
node instanceof DataFlow::ArgumentNode and
getElementType*(node.getType()) = containerType and
cs.asOneContent() = c
getElementType*(node.getType()) = containerType
|
containerType instanceof ArrayType and
c instanceof DataFlow::ArrayContent
@@ -143,7 +142,7 @@ predicate elementWriteStep(DataFlow::Node pred, DataFlow::Node succ) {
any(DataFlow::Write w).writesElement(succ.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, pred)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(pred.(DataFlowPrivate::FlowSummaryNode)
.getSummaryNode(), any(DataFlow::ArrayContent ac).asContentSet(),
.getSummaryNode(), any(DataFlow::Content c | c instanceof DataFlow::ArrayContent),
succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode())
}

View File

@@ -21,7 +21,7 @@ module GinCors {
/**
* A write to the value of Access-Control-Allow-Credentials header
*/
class AllowCredentialsWrite extends UniversalAllowCredentialsWrite {
class AllowCredentialsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowCredentialsWrite() {
@@ -35,12 +35,12 @@ module GinCors {
/**
* Get config struct holding header values
*/
override DataFlow::Node getBase() { result = base }
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
override GinConfig getConfig() {
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
@@ -55,7 +55,7 @@ module GinCors {
/**
* A write to the value of Access-Control-Allow-Origins header
*/
class AllowOriginsWrite extends UniversalOriginWrite {
class AllowOriginsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowOriginsWrite() {
@@ -69,12 +69,12 @@ module GinCors {
/**
* Get config struct holding header values
*/
override DataFlow::Node getBase() { result = base }
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
override GinConfig getConfig() {
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
@@ -89,7 +89,7 @@ module GinCors {
/**
* A write to the value of Access-Control-Allow-Origins of value "*", overriding AllowOrigins
*/
class AllowAllOriginsWrite extends UniversalAllowAllOriginsWrite {
class AllowAllOriginsWrite extends DataFlow::ExprNode {
DataFlow::Node base;
AllowAllOriginsWrite() {
@@ -103,12 +103,12 @@ module GinCors {
/**
* Get config struct holding header values
*/
override DataFlow::Node getBase() { result = base }
DataFlow::Node getBase() { result = base }
/**
* Get config variable holding header values
*/
override GinConfig getConfig() {
GinConfig getConfig() {
exists(GinConfig gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =

View File

@@ -1,184 +0,0 @@
/**
* Provides classes for modeling the `github.com/rs/cors` package.
*/
import go
/**
* An abstract class for modeling the Go CORS handler model origin write.
*/
abstract class UniversalOriginWrite extends DataFlow::ExprNode {
/**
* Get config variable holding header values
*/
abstract DataFlow::Node getBase();
/**
* Get config variable holding header values
*/
abstract Variable getConfig();
}
/**
* An abstract class for modeling the Go CORS handler model allow all origins write.
*/
abstract class UniversalAllowAllOriginsWrite extends DataFlow::ExprNode {
/**
* Get config variable holding header values
*/
abstract DataFlow::Node getBase();
/**
* Get config variable holding header values
*/
abstract Variable getConfig();
}
/**
* An abstract class for modeling the Go CORS handler model allow credentials write.
*/
abstract class UniversalAllowCredentialsWrite extends DataFlow::ExprNode {
/**
* Get config struct holding header values
*/
abstract DataFlow::Node getBase();
/**
* Get config variable holding header values
*/
abstract Variable getConfig();
}
/**
* Provides classes for modeling the `github.com/rs/cors` package.
*/
module RsCors {
/** Gets the package name `github.com/gin-gonic/gin`. */
string packagePath() { result = package("github.com/rs/cors", "") }
/**
* A new function create a new rs Handler
*/
class New extends Function {
New() { exists(Function f | f.hasQualifiedName(packagePath(), "New") | this = f) }
}
/**
* A write to the value of Access-Control-Allow-Credentials header
*/
class AllowCredentialsWrite extends UniversalAllowCredentialsWrite {
DataFlow::Node base;
AllowCredentialsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Options", "AllowCredentials") and
w.writesField(base, f, this) and
this.getType() instanceof BoolType
)
}
/**
* Get options struct holding header values
*/
override DataFlow::Node getBase() { result = base }
/**
* Get options variable holding header values
*/
override RsOptions getConfig() {
exists(RsOptions gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A write to the value of Access-Control-Allow-Origins header
*/
class AllowOriginsWrite extends UniversalOriginWrite {
DataFlow::Node base;
AllowOriginsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Options", "AllowedOrigins") and
w.writesField(base, f, this) and
this.asExpr() instanceof SliceLit
)
}
/**
* Get options struct holding header values
*/
override DataFlow::Node getBase() { result = base }
/**
* Get options variable holding header values
*/
override RsOptions getConfig() {
exists(RsOptions gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A write to the value of Access-Control-Allow-Origins of value "*", overriding AllowOrigins
*/
class AllowAllOriginsWrite extends UniversalAllowAllOriginsWrite {
DataFlow::Node base;
AllowAllOriginsWrite() {
exists(Field f, Write w |
f.hasQualifiedName(packagePath(), "Options", "AllowAllOrigins") and
w.writesField(base, f, this) and
this.getType() instanceof BoolType
)
}
/**
* Get options struct holding header values
*/
override DataFlow::Node getBase() { result = base }
/**
* Get options variable holding header values
*/
override RsOptions getConfig() {
exists(RsOptions gc |
(
gc.getV().getBaseVariable().getDefinition().(SsaExplicitDefinition).getRhs() =
base.asInstruction() or
gc.getV().getAUse() = base
) and
result = gc
)
}
}
/**
* A variable of type Options that holds the headers to be set.
*/
class RsOptions extends Variable {
SsaWithFields v;
RsOptions() {
this = v.getBaseVariable().getSourceVariable() and
exists(Type t | t.hasQualifiedName(packagePath(), "Options") | v.getType() = t)
}
/**
* Get variable declaration of Options
*/
SsaWithFields getV() { result = v }
}
}

View File

@@ -122,7 +122,7 @@ module NetHttp {
|
lastParamIndex = call.getCall().getCalleeType().getNumParameter() - 1 and
varArgsSliceArgument = SummaryComponentStack::argument(lastParamIndex) and
arrayContentSC = SummaryComponent::content(arrayContent.asContentSet()) and
arrayContentSC = SummaryComponent::content(arrayContent) and
stack = SummaryComponentStack::push(arrayContentSC, varArgsSliceArgument)
)
else stack = SummaryComponentStack::argument(n)

View File

@@ -67,45 +67,4 @@ module TextTemplate {
input = inp and output = outp
}
}
private class ExecuteTemplateMethod extends Method {
int inputArg;
ExecuteTemplateMethod() {
exists(string name |
this.hasQualifiedName("text/template", "Template", name) and
(
name = "Execute" and inputArg = 1
or
name = "ExecuteTemplate" and inputArg = 2
)
)
}
int getInputArgIdx() { result = inputArg }
}
private class ExecuteTemplateFieldReader extends DataFlow::ImplicitFieldReadNode {
override predicate shouldImplicitlyReadAllFields(DataFlow::Node n) {
exists(ExecuteTemplateMethod m, DataFlow::MethodCallNode cn |
cn.getTarget() = m and
n = cn.getArgument(m.getInputArgIdx())
)
}
}
private class ExecuteTemplateFunctionModels extends TaintTracking::FunctionModel,
ExecuteTemplateMethod
{
FunctionInput inp;
FunctionOutput outp;
ExecuteTemplateFunctionModels() {
inp.isParameter(this.getInputArgIdx()) and outp.isParameter(0)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}

View File

@@ -72,7 +72,7 @@ module UntrustedToAllowOriginHeaderConfig implements DataFlow::ConfigSig {
module UntrustedToAllowOriginConfigConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
additional predicate isSinkWrite(DataFlow::Node sink, UniversalOriginWrite w) { sink = w }
additional predicate isSinkWrite(DataFlow::Node sink, GinCors::AllowOriginsWrite w) { sink = w }
predicate isSink(DataFlow::Node sink) { isSinkWrite(sink, _) }
}
@@ -102,17 +102,17 @@ predicate allowCredentialsIsSetToTrue(DataFlow::ExprNode allowOriginHW) {
allowCredentialsHW.getResponseWriter()
)
or
exists(UniversalAllowCredentialsWrite allowCredentialsGin |
exists(GinCors::AllowCredentialsWrite allowCredentialsGin |
allowCredentialsGin.getExpr().getBoolValue() = true
|
allowCredentialsGin.getConfig() = allowOriginHW.(UniversalOriginWrite).getConfig() and
not exists(UniversalAllowAllOriginsWrite allowAllOrigins |
allowCredentialsGin.getConfig() = allowOriginHW.(GinCors::AllowOriginsWrite).getConfig() and
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
allowAllOrigins.getExpr().getBoolValue() = true and
allowCredentialsGin.getConfig() = allowAllOrigins.getConfig()
)
or
allowCredentialsGin.getBase() = allowOriginHW.(UniversalOriginWrite).getBase() and
not exists(UniversalAllowAllOriginsWrite allowAllOrigins |
allowCredentialsGin.getBase() = allowOriginHW.(GinCors::AllowOriginsWrite).getBase() and
not exists(GinCors::AllowAllOriginsWrite allowAllOrigins |
allowAllOrigins.getExpr().getBoolValue() = true and
allowCredentialsGin.getBase() = allowAllOrigins.getBase()
)
@@ -150,7 +150,7 @@ predicate allowOriginIsNull(DataFlow::ExprNode allowOriginHW, string message) {
+ " is set to `true`"
or
allowOriginHW
.(UniversalOriginWrite)
.(GinCors::AllowOriginsWrite)
.asExpr()
.(SliceLit)
.getAnElement()

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 1.1.7-dev
version: 1.1.6
groups:
- go
- queries

View File

@@ -5,4 +5,3 @@
| CorsMisconfiguration.go:53:4:53:44 | call to Set | access-control-allow-origin header is set to a user-defined value, and access-control-allow-credentials is set to `true` |
| CorsMisconfiguration.go:60:4:60:56 | call to Set | access-control-allow-origin header is set to a user-defined value, and access-control-allow-credentials is set to `true` |
| CorsMisconfiguration.go:67:5:67:57 | call to Set | access-control-allow-origin header is set to a user-defined value, and access-control-allow-credentials is set to `true` |
| RsCors.go:11:21:11:59 | slice literal | access-control-allow-origin header is set to `null`, and access-control-allow-credentials is set to `true` |

View File

@@ -1,39 +0,0 @@
package main
import (
"net/http"
"github.com/rs/cors"
)
func rs_vulnerable() {
c := cors.New(cors.Options{
AllowedOrigins: []string{"null", "http://foo.com:8080"},
AllowCredentials: true,
// Enable Debugging for testing, consider disabling in production
Debug: true,
})
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("{\"hello\": \"world\"}"))
})
http.ListenAndServe(":8080", c.Handler(handler))
}
func rs_safe() {
c := cors.New(cors.Options{
AllowedOrigins: []string{"http://foo.com:8080"},
AllowCredentials: true,
// Enable Debugging for testing, consider disabling in production
Debug: true,
})
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("{\"hello\": \"world\"}"))
})
http.ListenAndServe(":8080", c.Handler(handler))
}

View File

@@ -5,7 +5,6 @@ go 1.21
require (
github.com/gin-contrib/cors v1.4.0
github.com/gin-gonic/gin v1.9.1
github.com/rs/cors v1.10.1
)
require (

View File

@@ -1,53 +0,0 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/rs/cors, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/rs/cors (exports: Options; functions: New)
// Package cors is a stub of github.com/rs/cors, generated by depstubber.
package cors
import (
http "net/http"
)
type Cors struct {
Log Logger
}
func (_ *Cors) Handler(_ http.Handler) http.Handler {
return nil
}
func (_ *Cors) HandlerFunc(_ http.ResponseWriter, _ *http.Request) {}
func (_ *Cors) OriginAllowed(_ *http.Request) bool {
return false
}
func (_ *Cors) ServeHTTP(_ http.ResponseWriter, _ *http.Request, _ http.HandlerFunc) {}
type Logger interface {
Printf(_ string, _ ...interface{})
}
func New(_ Options) *Cors {
return nil
}
type Options struct {
AllowedOrigins []string
AllowOriginFunc func(string) bool
AllowOriginRequestFunc func(*http.Request, string) bool
AllowOriginVaryRequestFunc func(*http.Request, string) (bool, []string)
AllowedMethods []string
AllowedHeaders []string
ExposedHeaders []string
MaxAge int
AllowCredentials bool
AllowPrivateNetwork bool
OptionsPassthrough bool
OptionsSuccessStatus int
Debug bool
Logger Logger
}

View File

@@ -4,9 +4,6 @@ github.com/gin-contrib/cors
# github.com/gin-gonic/gin v1.9.1
## explicit
github.com/gin-gonic/gin
# github.com/rs/cors v1.10.1
## explicit
github.com/rs/cors
# github.com/bytedance/sonic v1.9.1
## explicit
github.com/bytedance/sonic

View File

@@ -1,9 +0,0 @@
import go
import utils.test.InlineFlowTest
string getArgString(DataFlow::Node src, DataFlow::Node sink) {
exists(sink) and
result = src.(DataFlow::CallNode).getArgument(0).getExactValue()
}
import TaintFlowTestArgString<DefaultFlowConfig, getArgString/2>

View File

@@ -1,60 +0,0 @@
package xyz
import (
"bytes"
"text/template"
)
type Inner1 struct {
Data string
}
type Inner2 struct {
Data string
}
type Inner3 struct {
Data string
}
type HasInner3Slice struct {
Slice []Inner3
}
type Outer struct {
SliceField []Inner1
PtrField *Inner2
MapField map[string]Inner3
DeepField HasInner3Slice
}
func source(n int) string { return "dummy" }
func sink(arg any) {}
func test() {
source1 := source(1)
source2 := source(2)
source3 := source(3)
source4 := source(4)
toSerialize := Outer{[]Inner1{{source1}}, &Inner2{source2}, map[string]Inner3{"key": {source3}},
HasInner3Slice{[]Inner3{{source4}}}}
buff1 := new(bytes.Buffer)
buff2 := new(bytes.Buffer)
bytes1 := make([]byte, 10)
bytes2 := make([]byte, 10)
tmpl, _ := template.New("test").Parse("Template text goes here (irrelevant for test)")
tmpl.ExecuteTemplate(buff1, "test", toSerialize)
buff1.Read(bytes1)
sink(bytes1) // $ hasTaintFlow=1 hasTaintFlow=2 hasTaintFlow=3 hasTaintFlow=4
// Read `buff2` via an `any`-typed variable, to ensure the static type of the argument to tmpl.Execute makes no difference to the result
var toSerializeAsAny any
toSerializeAsAny = toSerialize
tmpl.Execute(buff2, toSerializeAsAny)
buff2.Read(bytes2)
sink(bytes2) // $ hasTaintFlow=1 hasTaintFlow=2 hasTaintFlow=3 hasTaintFlow=4
}

View File

@@ -1,3 +0,0 @@
description: Add databaseMetadata relation
compatibility: full
databaseMetadata.rel: delete

Binary file not shown.

Binary file not shown.

View File

@@ -25,19 +25,7 @@ import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.typeOrNull
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.types.typeWithArguments
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrStarProjection
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
@@ -2305,7 +2293,7 @@ open class KotlinFileExtractor(
// synthesised and inherit the annotation from the delegate (which given it has
// @NotNull, is likely written in Java)
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.takeUnless {
t.isNullableCodeQL() ||
t.isNullable() ||
primitiveTypeMapping.getPrimitiveInfo(t) != null ||
hasExistingAnnotation(it)
}
@@ -3987,7 +3975,7 @@ open class KotlinFileExtractor(
target.parent
} else {
val st = extensionReceiverParameter.type as? IrSimpleType
if (isNullable != null && st?.isNullableCodeQL() != isNullable) {
if (isNullable != null && st?.isNullable() != isNullable) {
verboseln("Nullablility of type didn't match")
return false
}
@@ -4633,9 +4621,9 @@ open class KotlinFileExtractor(
val isPrimitiveArrayCreation = !isBuiltinCallKotlin(c, "arrayOf")
val elementType =
if (isPrimitiveArrayCreation) {
c.type.getArrayElementTypeCodeQL(pluginContext.irBuiltIns)
c.type.getArrayElementType(pluginContext.irBuiltIns)
} else {
// TODO: is there any reason not to always use getArrayElementTypeCodeQL?
// TODO: is there any reason not to always use getArrayElementType?
if (c.typeArgumentsCount == 1) {
c.getTypeArgument(0).also {
if (it == null) {

View File

@@ -12,24 +12,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.addAnnotations
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.types.typeOrNull
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.types.typeWithArguments
import org.jetbrains.kotlin.ir.types.IrDynamicType
import org.jetbrains.kotlin.ir.types.IrErrorType
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrStarProjection
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
@@ -696,7 +679,7 @@ open class KotlinUsesExtractor(
private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
if (arrayType.isPrimitiveArray()) arrayType
else {
val componentType = arrayType.getArrayElementTypeCodeQL(pluginContext.irBuiltIns)
val componentType = arrayType.getArrayElementType(pluginContext.irBuiltIns)
val componentTypeBroadened =
when (componentType) {
is IrSimpleType ->
@@ -707,7 +690,7 @@ open class KotlinUsesExtractor(
val unchanged =
componentType == componentTypeBroadened &&
(arrayType.arguments[0] as? IrTypeProjection)?.variance == Variance.INVARIANT &&
componentType.isNullableCodeQL()
componentType.isNullable()
if (unchanged) arrayType
else
IrSimpleTypeImpl(
@@ -722,7 +705,7 @@ open class KotlinUsesExtractor(
Kotlin arrays can be broken down as:
isArray(t)
|- t.isBoxedArrayCodeQL
|- t.isBoxedArray
| |- t.isArray() e.g. Array<Boolean>, Array<Boolean?>
| |- t.isNullableArray() e.g. Array<Boolean>?, Array<Boolean?>?
|- t.isPrimitiveArray() e.g. BooleanArray
@@ -732,7 +715,7 @@ open class KotlinUsesExtractor(
Primitive arrays are represented as e.g. boolean[].
*/
private fun isArray(t: IrType) = t.isBoxedArrayCodeQL || t.isPrimitiveArray()
private fun isArray(t: IrType) = t.isBoxedArray || t.isPrimitiveArray()
data class ArrayInfo(
val elementTypeResults: TypeResults,
@@ -773,7 +756,7 @@ open class KotlinUsesExtractor(
) {
pluginContext.irBuiltIns.anyType
} else {
t.getArrayElementTypeCodeQL(pluginContext.irBuiltIns)
t.getArrayElementType(pluginContext.irBuiltIns)
}
val recInfo = useArrayType(elementType, t.isPrimitiveArray())
@@ -861,7 +844,7 @@ open class KotlinUsesExtractor(
if (
(context == TypeContext.RETURN ||
(context == TypeContext.OTHER && otherIsPrimitive)) &&
!s.isNullableCodeQL() &&
!s.isNullable() &&
getKotlinType(s)?.hasEnhancedNullability() != true &&
primitiveName != null
) {
@@ -877,7 +860,7 @@ open class KotlinUsesExtractor(
val kotlinClassId = useClassInstance(kotlinClass, listOf()).typeResult.id
val kotlinResult =
if (true) TypeResult(fakeKotlinType(), "TODO", "TODO")
else if (s.isNullableCodeQL()) {
else if (s.isNullable()) {
val kotlinSignature =
"$kotlinPackageName.$kotlinClassName?" // TODO: Is this right?
val kotlinLabel = "@\"kt_type;nullable;$kotlinPackageName.$kotlinClassName\""
@@ -919,21 +902,21 @@ open class KotlinUsesExtractor(
return extractErrorType()
}
}
(s.isBoxedArrayCodeQL && s.arguments.isNotEmpty()) || s.isPrimitiveArray() -> {
(s.isBoxedArray && s.arguments.isNotEmpty()) || s.isPrimitiveArray() -> {
val arrayInfo = useArrayType(s, false)
return arrayInfo.componentTypeResults
}
owner is IrClass -> {
val args = if (s.codeQlIsRawType()) null else s.arguments
return useSimpleTypeClass(owner, args, s.isNullableCodeQL())
return useSimpleTypeClass(owner, args, s.isNullable())
}
owner is IrTypeParameter -> {
val javaResult = useTypeParameter(owner)
val aClassId = makeClass("kotlin", "TypeParam") // TODO: Wrong
val kotlinResult =
if (true) TypeResult(fakeKotlinType(), "TODO", "TODO")
else if (s.isNullableCodeQL()) {
else if (s.isNullable()) {
val kotlinSignature = "${javaResult.signature}?" // TODO: Wrong
val kotlinLabel = "@\"kt_type;nullable;type_param\"" // TODO: Wrong
val kotlinId: Label<DbKt_nullable_type> =
@@ -1217,7 +1200,7 @@ open class KotlinUsesExtractor(
}
private fun extendsAdditionAllowed(t: IrType) =
if (t.isBoxedArrayCodeQL) {
if (t.isBoxedArray) {
if (t is IrSimpleType) {
arrayExtendsAdditionAllowed(t)
} else {
@@ -1510,7 +1493,7 @@ open class KotlinUsesExtractor(
}
} else {
t.classOrNull?.let { tCls ->
if (t.isBoxedArrayCodeQL) {
if (t.isBoxedArray) {
(t.arguments.singleOrNull() as? IrTypeProjection)?.let { elementTypeArg
->
val elementType = elementTypeArg.type
@@ -1523,7 +1506,7 @@ open class KotlinUsesExtractor(
)
return tCls
.typeWithArguments(listOf(newArg))
.codeQlWithHasQuestionMark(t.isNullableCodeQL())
.codeQlWithHasQuestionMark(t.isNullable())
}
}
}
@@ -2103,12 +2086,12 @@ open class KotlinUsesExtractor(
}
if (owner is IrClass) {
if (t.isBoxedArrayCodeQL) {
val elementType = t.getArrayElementTypeCodeQL(pluginContext.irBuiltIns)
if (t.isBoxedArray) {
val elementType = t.getArrayElementType(pluginContext.irBuiltIns)
val erasedElementType = erase(elementType)
return owner
.typeWith(erasedElementType)
.codeQlWithHasQuestionMark(t.isNullableCodeQL())
.codeQlWithHasQuestionMark(t.isNullable())
}
return if (t.arguments.isNotEmpty())

View File

@@ -5,7 +5,7 @@ import com.github.codeql.utils.versions.*
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.fir.java.VirtualFileBasedSourceElement
import org.jetbrains.kotlin.fir.java.JavaBinarySourceElement
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
@@ -89,8 +89,8 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? {
is BinaryJavaClass -> return element.virtualFile
}
}
is VirtualFileBasedSourceElement -> {
return cSource.virtualFile
is JavaBinarySourceElement -> {
return cSource.javaClass.virtualFile
}
is KotlinJvmBinarySourceElement -> {
val binaryClass = cSource.binaryClass

View File

@@ -5,7 +5,6 @@ import com.github.codeql.Logger
import com.github.codeql.getJavaEquivalentClassId
import com.github.codeql.utils.versions.codeQlWithHasQuestionMark
import com.github.codeql.utils.versions.createImplicitParameterDeclarationWithWrappedDescriptor
import com.github.codeql.utils.versions.*
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
@@ -19,18 +18,15 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.types.addAnnotations
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrStarProjection
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.constructedClassType
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.kotlinFqName
import org.jetbrains.kotlin.ir.util.parents
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
@@ -61,7 +57,7 @@ private fun IrSimpleType.substituteTypeArguments(
}
}
return IrSimpleTypeImpl(classifier, isNullableCodeQL(), newArguments, annotations)
return IrSimpleTypeImpl(classifier, isNullable(), newArguments, annotations)
}
/**
@@ -100,7 +96,7 @@ private fun subProjectedType(
else {
val newProjectedType =
substitutedTypeArg.type.let {
if (t.isNullableCodeQL()) it.codeQlWithHasQuestionMark(true) else it
if (t.isNullable()) it.codeQlWithHasQuestionMark(true) else it
}
val newVariance = combineVariance(outerVariance, substitutedTypeArg.variance)
makeTypeProjection(newProjectedType, newVariance)
@@ -117,7 +113,7 @@ private fun IrTypeArgument.upperBound(context: IrPluginContext) =
when (this.variance) {
Variance.INVARIANT -> this.type
Variance.IN_VARIANCE ->
if (this.type.isNullableCodeQL()) context.irBuiltIns.anyNType
if (this.type.isNullable()) context.irBuiltIns.anyNType
else context.irBuiltIns.anyType
Variance.OUT_VARIANCE -> this.type
}
@@ -132,7 +128,7 @@ private fun IrTypeArgument.lowerBound(context: IrPluginContext) =
Variance.INVARIANT -> this.type
Variance.IN_VARIANCE -> this.type
Variance.OUT_VARIANCE ->
if (this.type.isNullableCodeQL()) context.irBuiltIns.nothingNType
if (this.type.isNullable()) context.irBuiltIns.nothingNType
else context.irBuiltIns.nothingType
}
else -> context.irBuiltIns.nothingType
@@ -215,7 +211,7 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument =
this.type.let {
when (it) {
is IrSimpleType ->
if (it.isNullableCodeQL() == b) this
if (it.isNullable() == b) this
else makeTypeProjection(it.codeQlWithHasQuestionMark(b), this.variance)
else -> this
}

View File

@@ -1,5 +0,0 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
typealias IrBuiltIns = IrBuiltIns

View File

@@ -1,6 +1,5 @@
package org.jetbrains.kotlin.fir.java
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
@@ -8,6 +7,5 @@ import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
We need this class to exist, but the compiler will never give us an
instance of it.
*/
abstract class VirtualFileBasedSourceElement private constructor(val javaClass: BinaryJavaClass) : SourceElement {
abstract val virtualFile: VirtualFile
}
abstract class JavaBinarySourceElement private constructor(val javaClass: BinaryJavaClass) :
SourceElement {}

View File

@@ -1,11 +0,0 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.types.*
fun IrType.isNullableCodeQL(): Boolean =
this.isNullable()
val IrType.isBoxedArrayCodeQL: Boolean by IrType::isBoxedArray
fun IrType.getArrayElementTypeCodeQL(irBuiltIns: IrBuiltIns): IrType =
this.getArrayElementType(irBuiltIns)

View File

@@ -1,5 +0,0 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.IrBuiltIns
typealias IrBuiltIns = org.jetbrains.kotlin.ir.IrBuiltIns

View File

@@ -0,0 +1,3 @@
/*
The compiler provides this class, so we don't have to do anything.
*/

Some files were not shown because too many files have changed in this diff Show More