Compare commits

..

95 Commits

Author SHA1 Message Date
Óscar San José
7d30e3ca5e Merge pull request #21401 from github/release-prep/2.24.3
Release preparation for version 2.24.3
2026-03-02 17:10:28 +01:00
Óscar San José
df7379c0d2 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 14:32:16 +01:00
github-actions[bot]
7795badd18 Release preparation for version 2.24.3 2026-03-02 13:23:40 +00:00
yoff
600f585a31 Merge pull request #21296 from yoff/python/bool-comparison-guards
Python: Handle guards being compared to boolean literals
2026-02-26 21:13:51 +01:00
Tom Hvitved
4280d35bf3 Merge pull request #21366 from hvitved/rust/type-inference-unify-method-resolution
Rust: Unify logic in `MethodResolution`; remove `TypeQualifierIsInstantiationOfImplSelf` logic
2026-02-26 14:38:35 +01:00
Tom Hvitved
11a726d1b4 Address review comments 2026-02-26 14:23:41 +01:00
yoff
89e5a9bd72 Update python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll
Co-authored-by: Taus <tausbn@github.com>
2026-02-26 13:14:26 +01:00
yoff
cfbae50845 Python: convert barrier guard to MaD 2026-02-26 13:12:34 +01:00
yoff
9b9c9304c7 Python: simplify logic, suggested in review 2026-02-25 18:16:38 +01:00
yoff
c4f8748a42 Python: simplify barrier guard 2026-02-25 18:03:40 +01:00
Geoffrey White
5523b5e25f Merge pull request #21271 from geoffw0/neutralmodels
Rust: Add support for neutral models.
2026-02-25 16:15:55 +00:00
Paolo Tranquilli
4e4d0555c0 Merge pull request #21373 from github/redsun82/load-cc-explicitly
Bazel: load `rules_cc` and `rules_shell` explicitly
2026-02-25 16:10:16 +01:00
Geoffrey White
ccc318106e Rust: Add an empty.model.yml similar to the one in CPP, to avoid errors about missing extensionals. 2026-02-25 14:25:12 +00:00
Paolo Tranquilli
4d0c72eafe Bazel: add explicit rules_shell load 2026-02-25 14:05:53 +01:00
Paolo Tranquilli
15a2575949 Merge branch 'main' into redsun82/load-cc-explicitly 2026-02-25 13:59:29 +01:00
Paolo Tranquilli
968856ed96 Merge pull request #21371 from github/redsun82/fix-local-go-builds
Go: fix standalone build of the Go extractor
2026-02-25 13:52:49 +01:00
Paolo Tranquilli
5b5dc9c708 Bazel: load rules_cc explicitly
Turns out in https://github.com/github/codeql/pull/21371 I was right
about `java_*` rules not relying on autoload anywhere, but it turns out
some `cc_*` rules still relied on autoload. This autoload is currently
configured in the internal repository, but we want to remove it
eventually. This patch:
* adds explicit loads to `rules_cc`
* removes an obsolete file (that depedency has its own bazel module
  since some time, we just forgot to remove the old file)
2026-02-25 13:52:25 +01:00
Paolo Tranquilli
42e41c57d4 Go: fix standalone build of the Go extractor
https://github.com/github/codeql/pull/21276 worked together with the
internal changes but broke the standalone build of the Go extractor of
this repo in isolation.

The root cause was the lack of an auto-loaded `java_library` rule
definition. This fixes it.

I also checked this doesn't happen anywhere else.
2026-02-25 13:33:54 +01:00
Asger F
f0e665d08c Merge pull request #21349 from asgerf/mobx-wrapper
Support React components wrapped by 'mobx-react'
2026-02-25 09:24:45 +01:00
Tom Hvitved
de9b1adf63 Rust: Unify logic in MethodResolution; remove TypeQualifierIsInstantiationOfImplSelf logic 2026-02-25 09:05:58 +01:00
Tom Hvitved
018674cfde Merge pull request #21333 from hvitved/rust/type-inference-restrict-receiver-type-propagation
Rust: Restrict type propagation into receivers
2026-02-25 08:48:14 +01:00
Mathias Vorreiter Pedersen
266130b5cf Merge pull request #21360 from microsoft/unbreak-changes
C++: Provide `BarrierGuard` API without a `Unit` column when instantiating non-parameterized `BarrierGuard`s
2026-02-24 16:57:58 +00:00
Geoffrey White
8769059ce5 Rust: Remove another call to neutralModel we don't need to make explicitly. 2026-02-24 15:01:45 +00:00
Taus
6bfb1e1fae Merge pull request #21344 from github/tausbn/python-remove-points-to-from-metrics-libraries
Python: Remove points-to from metrics library
2026-02-24 15:55:16 +01:00
Taus
f107235db2 Update change note 2026-02-24 15:08:36 +01:00
Michael Nebel
3e2f6e571f Merge pull request #21351 from michaelnebel/csharp/fixpartialmethod
C#: Fix issue with partial method extraction.
2026-02-24 14:23:44 +01:00
Mathias Vorreiter Pedersen
ea9e4b3409 C++: Make a test slightly more verbose to catch this issue in the future. 2026-02-24 12:52:18 +00:00
Mathias Vorreiter Pedersen
d36350aca4 C++: Add change note. 2026-02-24 12:48:45 +00:00
Jeroen Ketema
0947323e78 Merge pull request #21359 from jketema/jketema/softfloat-revert
Revert SoftFloat Changes
2026-02-24 13:34:52 +01:00
Mathias Vorreiter Pedersen
15af6c1b20 C++: Provide barrier node API without the unit column when instantiating non-parameterized barrier guards. 2026-02-24 12:32:23 +00:00
Tom Hvitved
f9869daa91 Address review comments 2026-02-24 12:12:47 +01:00
Tom Hvitved
61d809b41a Rust: Add another type inference test 2026-02-24 12:08:40 +01:00
Jeroen Ketema
197ee9b9a6 Revert "Merge pull request #21208 from jketema/jketema/softfloat"
This reverts commit 99de5d4238, reversing
changes made to 12bd709219.
2026-02-24 11:08:25 +01:00
yoff
7df44f9418 python: add change note 2026-02-24 10:00:22 +01:00
yoff
7351e82c92 python: handle guards compared to boolean literals 2026-02-24 10:00:22 +01:00
yoff
8488039fb9 python: add tests for guards compared to booleans 2026-02-24 10:00:21 +01:00
Michael Nebel
7de476aeb0 C#: Add change note. 2026-02-24 07:56:02 +01:00
Michael Nebel
a255b4f50f C#: Update test expected output. 2026-02-24 07:56:00 +01:00
Michael Nebel
003b539287 C#: Streamline the partial implementation for properties and events. 2026-02-24 07:55:59 +01:00
Michael Nebel
03a54bfbf9 C#: Update test expected output. 2026-02-24 07:55:57 +01:00
Michael Nebel
d3fcc2a6cc C#: Extract partial method declaration. 2026-02-24 07:55:54 +01:00
Michael Nebel
e8427a59f5 C#: Cache the Block and ExpressionBody and streamline implementation too look for both when checking whether a body is available. 2026-02-24 07:55:53 +01:00
Geoffrey White
e9511560b7 Rust: Autoformat. 2026-02-23 19:51:22 +00:00
Geoffrey White
6b7f339287 Rust: Define neutralElement in the shared data flow input. 2026-02-23 19:38:13 +00:00
Jon Janego
0151e8427c Merge pull request #21357 from github/codeql-spark-run-22317536589
Update changelog documentation site
2026-02-23 13:35:16 -06:00
Jon Janego
e14b4f1c5c Merge branch 'main' into codeql-spark-run-22317536589 2026-02-23 11:52:17 -06:00
Jon Janego
365bae1f9c Fix formatting in codeql-cli-2.23.1.rst 2026-02-23 11:50:46 -06:00
Jon Janego
79ac95d8a8 Fix syntax error with '=' in format specifier 2026-02-23 11:50:03 -06:00
Jon Janego
8719072519 Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-23 11:46:50 -06:00
Jon Janego
af0bfe0981 Promote CORS configuration query to default suite 2026-02-23 11:46:30 -06:00
Jon Janego
d546b85163 Fix formatting for Kotlin version support note 2026-02-23 11:45:59 -06:00
Jon Janego
2969feef89 Fix formatting in Kotlin version support note 2026-02-23 11:45:30 -06:00
Jon Janego
9773775a08 Update codeql-cli-2.19.1.rst 2026-02-23 11:44:53 -06:00
github-actions[bot]
532e1feacc update codeql documentation 2026-02-23 17:40:16 +00:00
Michael Nebel
7d7bbf2a50 C#: Add data flow test for partial method. 2026-02-23 15:10:15 +01:00
Michael Nebel
0e543a9843 C#: Update partial method test to count the number of extracted bodies. 2026-02-23 15:10:14 +01:00
Michael Nebel
a83c53ec9a C#: Add a partial method example with a body. 2026-02-23 15:10:12 +01:00
Owen Mansel-Chan
ada9c452f0 Merge pull request #21336 from owen-mc/js/accept-mad-sanitizers
JS: Accept MaD sanitizers for queries with MaD sinks
2026-02-23 13:44:54 +00:00
Jeroen Ketema
99de5d4238 Merge pull request #21208 from jketema/jketema/softfloat
C++: Update expected test results after extractor changes
2026-02-23 13:52:43 +01:00
Owen Mansel-Chan
12bd709219 Merge pull request #21341 from owen-mc/rb/accept-mad-sanitizers
Ruby: Accept MaD sanitizers for queries with MaD sinks and convert some existing sanitizers
2026-02-23 11:44:05 +00:00
Jeroen Ketema
a935d97190 C++: Update expected test results after extractor changes 2026-02-23 11:54:58 +01:00
Asger F
27638c7029 JS: Add change note 2026-02-20 11:20:46 +01:00
Taus
07099f17d6 Python: Add change note 2026-02-19 12:32:27 +00:00
Taus
e8de8433f4 Python: Update all metrics-dependant queries
The ones that no longer require points-to no longer import
`LegacyPointsTo`. The ones that do use the specific
`...MetricsWithPointsTo` classes that are applicable.
2026-02-19 12:32:27 +00:00
Taus
20fea3955e Python: Remove points-to from Metrics.qll
Moves the classes/predicates that _actually_ depend on points-to to the
`LegacyPointsTo` module, leaving behind a module that contains all of
the metrics-related stuff (line counts, nesting depth, etc.) that don't
need points-to to be evaluated.

Consequently, `Metrics` is now no longer a private import in
`python.qll`.
2026-02-19 12:32:27 +00:00
Asger F
a684943bb7 JS: Model mobx-react{-lite} as higher-order component builders 2026-02-19 11:26:46 +01:00
Asger F
a0099d64c8 JS: Add mobx-react and mobx-react-lite tests 2026-02-19 11:26:44 +01:00
Owen Mansel-Chan
1d6b8c5120 Use postprocessing queries for unrelated test
Need to do this because the model numbering was changing. At the same
time we may as well use inline expectations.
2026-02-18 13:49:53 +00:00
Owen Mansel-Chan
05d681fe19 Update taintstep test for models becoming MaD 2026-02-18 13:49:50 +00:00
Owen Mansel-Chan
f577e973bc Update other test in same folder 2026-02-18 13:39:06 +00:00
Owen Mansel-Chan
1bff7a3eb8 Add change note 2026-02-17 22:29:35 +00:00
Owen Mansel-Chan
eb7f1989c7 Reinstate ql model for String#shellescape 2026-02-17 22:27:15 +00:00
Owen Mansel-Chan
de5470a85c Add MaD barriers for Shellwords.escape and shellescape
Note that this will only block flow for queries that use the kind `command-injection`.
2026-02-17 22:27:13 +00:00
Owen Mansel-Chan
b3681f7a0c Model flow through Shellwords escape and shellescape 2026-02-17 22:27:11 +00:00
Owen Mansel-Chan
6294c3b3b8 Remove Shellwords sanitizer in ql
Note that some sanitizers had no effect because flow through those functions wasn't modeled.
2026-02-17 22:27:10 +00:00
Owen Mansel-Chan
4aee99f0eb Reinstate SQLite3 sanitizer in MaD 2026-02-17 22:27:08 +00:00
Owen Mansel-Chan
5df695bec9 Move SQLite3 flow model to MaD and remove ql sanitizer 2026-02-17 22:27:06 +00:00
Owen Mansel-Chan
1fa183ee2a Improve Sqlite3 test 2026-02-17 22:27:04 +00:00
Owen Mansel-Chan
d4bb92b038 Reinstate Mysql2 sanitizer in MaD 2026-02-17 22:27:03 +00:00
Owen Mansel-Chan
3e4f42f8a3 Move Mysql2 flow model to MaD and remove ql sanitizer 2026-02-17 22:27:01 +00:00
Owen Mansel-Chan
fc429c1757 Improve Mysql2 test 2026-02-17 22:27:00 +00:00
Owen Mansel-Chan
1d7a39a093 Change how sql-injection barriers are accepted 2026-02-17 22:26:58 +00:00
Owen Mansel-Chan
05f9b4124d Revert "javascript: remove sanitizer to be replaced by model"
This reverts commit da2f77d615.
2026-02-17 14:39:04 +00:00
Owen Mansel-Chan
b8f9dd9de5 Revert "javascript: add MaD model"
This reverts commit 75bd4a7a12.
2026-02-17 14:38:56 +00:00
Owen Mansel-Chan
3dc465f167 Accept MaD sanitizers for queries with MaD sinks 2026-02-17 12:48:36 +00:00
Owen Mansel-Chan
61e8f91404 Accept MaD sanitizers for queries with MaD sinks 2026-02-17 12:45:24 +00:00
Tom Hvitved
e587541e55 Rust: Restrict type propagation into receivers 2026-02-17 13:42:56 +01:00
Tom Hvitved
8a051d7e57 Rust: Add type inference test 2026-02-17 13:40:16 +01:00
Geoffrey White
a5aeadd31d Rust: Fix for neutral summaries. 2026-02-06 18:15:13 +00:00
Geoffrey White
08174d7ec9 Rust: Add test cases for summaries as well. 2026-02-06 18:05:54 +00:00
Geoffrey White
05a487ec3b Rust: Repair following merge. 2026-02-05 15:56:58 +00:00
Geoffrey White
c0a5c63e8e Merge branch 'main' into neutralmodels 2026-02-05 15:53:28 +00:00
Geoffrey White
9de5f5c72b Rust: Clean up and change note. 2026-02-05 08:58:08 +00:00
Geoffrey White
d40071321a Rust: Implement neutral models for Rust. 2026-02-04 18:58:09 +00:00
Geoffrey White
97f7dcb04a Rust: Add dataflow test cases for neutral models. 2026-02-04 17:43:05 +00:00
377 changed files with 2942 additions and 4675 deletions

View File

@@ -1,3 +1,7 @@
## 0.4.29
No user-facing changes.
## 0.4.28
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.4.29
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.28
lastReleaseVersion: 0.4.29

View File

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

View File

@@ -1,3 +1,7 @@
## 0.6.21
No user-facing changes.
## 0.6.20
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.6.21
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.20
lastReleaseVersion: 0.6.21

View File

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

View File

@@ -1,3 +1,18 @@
## 8.0.0
### Breaking Changes
* CodeQL version 2.24.2 accidentally introduced a syntactical breaking change to `BarrierGuard<...>::getAnIndirectBarrierNode` and `InstructionBarrierGuard<...>::getAnIndirectBarrierNode`. These breaking changes have now been reverted so that the original code compiles again.
* `MustFlow`, the inter-procedural must-flow data flow analysis library, has been re-worked to use parameterized modules. Like in the case of data flow and taint tracking, instead of extending the `MustFlowConfiguration` class, the user should now implement a module with the `MustFlow::ConfigSig` signature, and instantiate the `MustFlow::Global` parameterized module with the implemented module.
### Minor Analysis Improvements
* Refactored the "Year field changed using an arithmetic operation without checking for leap year" query (`cpp/leap-year/unchecked-after-arithmetic-year-modification`) to address large numbers of false positive results.
### Bug Fixes
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.
## 7.1.1
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Refactored the "Year field changed using an arithmetic operation without checking for leap year" query (`cpp/leap-year/unchecked-after-arithmetic-year-modification`) to address large numbers of false positive results.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* `MustFlow`, the inter-procedural must-flow data flow analysis library, has been re-worked to use parameterized modules. Like in the case of data flow and taint tracking, instead of extending the `MustFlowConfiguration` class, the user should now implement a module with the `MustFlow::ConfigSig` signature, and instantiate the `MustFlow::Global` parameterized module with the implemented module.

View File

@@ -0,0 +1,14 @@
## 8.0.0
### Breaking Changes
* CodeQL version 2.24.2 accidentally introduced a syntactical breaking change to `BarrierGuard<...>::getAnIndirectBarrierNode` and `InstructionBarrierGuard<...>::getAnIndirectBarrierNode`. These breaking changes have now been reverted so that the original code compiles again.
* `MustFlow`, the inter-procedural must-flow data flow analysis library, has been re-worked to use parameterized modules. Like in the case of data flow and taint tracking, instead of extending the `MustFlowConfiguration` class, the user should now implement a module with the `MustFlow::ConfigSig` signature, and instantiate the `MustFlow::Global` parameterized module with the implemented module.
### Minor Analysis Improvements
* Refactored the "Year field changed using an arithmetic operation without checking for leap year" query (`cpp/leap-year/unchecked-after-arithmetic-year-modification`) to address large numbers of false positive results.
### Bug Fixes
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.1.1
lastReleaseVersion: 8.0.0

View File

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

View File

@@ -2641,7 +2641,54 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
exists(unit)
}
import ParameterizedBarrierGuard<Unit, guardChecks/4>
private module P = ParameterizedBarrierGuard<Unit, guardChecks/4>;
predicate getABarrierNode = P::getABarrierNode/0;
/**
* Gets an indirect expression node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
*
* For example, given the following code:
* ```cpp
* int* p;
* // ...
* *p = source();
* if(is_safe_pointer(p)) {
* sink(*p);
* }
* ```
* and the following barrier guard check:
* ```ql
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
* exists(Call call |
* g.getUnconvertedResultExpression() = call and
* call.getTarget().hasName("is_safe_pointer") and
* e = call.getAnArgument() and
* branch = true
* )
* }
* ```
* implementing `isBarrier` as:
* ```ql
* predicate isBarrier(DataFlow::Node barrier) {
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
* }
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
Node getAnIndirectBarrierNode(int indirectionIndex) {
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
}
/**
* Gets an indirect expression node that is safely guarded by the given guard check.
*
* See `getAnIndirectBarrierNode/1` for examples.
*/
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
}
private module InstrWithParam<ParamSig P> {
@@ -2752,7 +2799,20 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
exists(unit)
}
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
private module P = ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>;
predicate getABarrierNode = P::getABarrierNode/0;
/**
* Gets an indirect node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
*/
Node getAnIndirectBarrierNode(int indirectionIndex) {
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
}
/** Gets an indirect node that is safely guarded by the given guard check. */
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
}
/**

View File

@@ -1,3 +1,7 @@
## 1.5.12
No user-facing changes.
## 1.5.11
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.5.12
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.5.11
lastReleaseVersion: 1.5.12

View File

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

View File

@@ -15,7 +15,10 @@ predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boole
module BarrierGuard = DataFlow::InstructionBarrierGuard<instructionGuardChecks/3>;
predicate indirectBarrierGuard(DataFlow::Node node, string s) {
node = BarrierGuard::getAnIndirectBarrierNode(_) and
// This any(...) could technically be removed, but it helps us verify that we don't
// accidentially change the API of this predicate (for instance, by having
// the column be a unit parameter).
node = BarrierGuard::getAnIndirectBarrierNode(any(int indirectionIndex)) and
if node.isGLValue()
then s = "glval<" + node.getType().toString().replaceAll(" ", "") + ">"
else s = node.getType().toString().replaceAll(" ", "")

View File

@@ -728,6 +728,15 @@ namespace Semmle.Extraction.CSharp
public static INamedTypeSymbol? GetNonObjectBaseType(this ITypeSymbol symbol, Context cx) =>
symbol is ITypeParameterSymbol || SymbolEqualityComparer.Default.Equals(symbol.BaseType, cx.Compilation.ObjectType) ? null : symbol.BaseType;
public static IMethodSymbol GetBodyDeclaringSymbol(this IMethodSymbol method) =>
method.PartialImplementationPart ?? method;
public static IPropertySymbol GetBodyDeclaringSymbol(this IPropertySymbol property) =>
property.PartialImplementationPart ?? property;
public static IEventSymbol GetBodyDeclaringSymbol(this IEventSymbol symbol) =>
symbol.PartialImplementationPart ?? symbol;
[return: NotNullIfNotNull(nameof(symbol))]
public static IEntity? CreateEntity(this Context cx, ISymbol symbol)
{

View File

@@ -70,7 +70,7 @@ namespace Semmle.Extraction.CSharp.Entities
Overrides(trapFile);
if (Symbol.FromSource() && Block is null)
if (Symbol.FromSource() && !HasBody)
{
trapFile.compiler_generated(this);
}

View File

@@ -9,9 +9,14 @@ namespace Semmle.Extraction.CSharp.Entities
{
internal abstract class CachedSymbol<T> : CachedEntity<T> where T : class, ISymbol
{
private readonly Lazy<BlockSyntax?> blockLazy;
private readonly Lazy<ExpressionSyntax?> expressionBodyLazy;
protected CachedSymbol(Context cx, T init)
: base(cx, init)
{
blockLazy = new Lazy<BlockSyntax?>(() => GetBlock(Symbol));
expressionBodyLazy = new Lazy<ExpressionSyntax?>(() => GetExpressionBody(Symbol));
}
public virtual Type? ContainingType => Symbol.ContainingType is not null
@@ -87,31 +92,29 @@ namespace Semmle.Extraction.CSharp.Entities
Context.BindComments(this, FullLocation);
}
protected virtual T BodyDeclaringSymbol => Symbol;
public BlockSyntax? Block
private static BlockSyntax? GetBlock(T symbol)
{
get
{
return BodyDeclaringSymbol.DeclaringSyntaxReferences
return symbol.DeclaringSyntaxReferences
.SelectMany(r => r.GetSyntax().ChildNodes())
.OfType<BlockSyntax>()
.FirstOrDefault();
}
}
public ExpressionSyntax? ExpressionBody
private static ExpressionSyntax? GetExpressionBody(T symbol)
{
get
{
return BodyDeclaringSymbol.DeclaringSyntaxReferences
return symbol.DeclaringSyntaxReferences
.SelectMany(r => r.GetSyntax().ChildNodes())
.OfType<ArrowExpressionClauseSyntax>()
.Select(arrow => arrow.Expression)
.FirstOrDefault();
}
}
public BlockSyntax? Block => blockLazy.Value;
public ExpressionSyntax? ExpressionBody => expressionBodyLazy.Value;
public bool HasBody => Block is not null || ExpressionBody is not null;
public virtual bool IsSourceDeclaration => Symbol.IsSourceDeclaration();
public override bool NeedsPopulation => Context.Defines(Symbol);

View File

@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CSharp.Entities
return;
}
if (MakeSynthetic)
if (MakeSyntheticBody)
{
// Create a synthetic empty body for primary and default constructors.
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
@@ -60,7 +60,7 @@ namespace Semmle.Extraction.CSharp.Entities
// Do not extract initializers for constructed types.
// Extract initializers for constructors with a body, primary constructors
// and default constructors for classes and structs declared in source code.
if (Block is null && ExpressionBody is null && !MakeSynthetic || Context.OnlyScaffold)
if (!HasBody && !MakeSyntheticBody || Context.OnlyScaffold)
{
return;
}
@@ -211,7 +211,7 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary>
private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation);
private bool MakeSynthetic => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
private bool MakeSyntheticBody => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
[return: NotNullIfNotNull(nameof(constructor))]
public static new Constructor? Create(Context cx, IMethodSymbol? constructor)

View File

@@ -11,10 +11,6 @@ namespace Semmle.Extraction.CSharp.Entities
private Event(Context cx, IEventSymbol init)
: base(cx, init) { }
protected override IEventSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(ContainingType!);
@@ -31,8 +27,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type);
trapFile.events(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
var adder = BodyDeclaringSymbol.AddMethod;
var remover = BodyDeclaringSymbol.RemoveMethod;
var adder = Symbol.AddMethod;
var remover = Symbol.RemoveMethod;
if (adder is not null)
Method.Create(Context, adder);
@@ -76,7 +72,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol);
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol.GetBodyDeclaringSymbol());
private class EventFactory : CachedEntityFactory<IEventSymbol, Event>
{

View File

@@ -59,7 +59,7 @@ namespace Semmle.Extraction.CSharp.Entities
Overrides(trapFile);
if (Symbol.FromSource() && Block is null)
if (Symbol.FromSource() && !HasBody)
{
trapFile.compiler_generated(this);
}

View File

@@ -20,8 +20,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type);
trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition);
var getter = BodyDeclaringSymbol.GetMethod;
var setter = BodyDeclaringSymbol.SetMethod;
var getter = Symbol.GetMethod;
var setter = Symbol.SetMethod;
if (getter is null && setter is null)
Context.ModelError(Symbol, "No indexer accessor defined");
@@ -81,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.Type, this, type);
}
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop);
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
public override void WriteId(EscapingTextWriter trapFile)
{

View File

@@ -85,7 +85,7 @@ namespace Semmle.Extraction.CSharp.Entities
else
Expression.Create(Context, expr!, this, 0);
NumberOfLines(trapFile, BodyDeclaringSymbol, this);
NumberOfLines(trapFile, Symbol, this);
});
}
}

View File

@@ -14,14 +14,12 @@ namespace Semmle.Extraction.CSharp.Entities
public override string Name => Symbol.GetName();
protected override IMethodSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public IMethodSymbol SourceDeclaration => Symbol.OriginalDefinition;
public override Microsoft.CodeAnalysis.Location ReportingLocation =>
IsCompilerGeneratedDelegate()
? Symbol.ContainingType.GetSymbolLocation()
: BodyDeclaringSymbol.GetSymbolLocation();
: Symbol.GetSymbolLocation();
public override bool NeedsPopulation =>
(base.NeedsPopulation || IsCompilerGeneratedDelegate()) &&
@@ -77,7 +75,7 @@ namespace Semmle.Extraction.CSharp.Entities
cx.ExtractionContext.Logger.LogWarning("Reduced extension method symbols should not be directly extracted.");
}
return OrdinaryMethodFactory.Instance.CreateEntityFromSymbol(cx, method);
return OrdinaryMethodFactory.Instance.CreateEntityFromSymbol(cx, method.GetBodyDeclaringSymbol());
}
private class OrdinaryMethodFactory : CachedEntityFactory<IMethodSymbol, OrdinaryMethod>

View File

@@ -21,10 +21,6 @@ namespace Semmle.Extraction.CSharp.Entities
private Type Type => type.Value;
protected override IPropertySymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(Type);
@@ -46,8 +42,8 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type;
trapFile.properties(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
var getter = BodyDeclaringSymbol.GetMethod;
var setter = BodyDeclaringSymbol.SetMethod;
var getter = Symbol.GetMethod;
var setter = Symbol.SetMethod;
if (getter is not null)
Method.Create(Context, getter);
@@ -132,7 +128,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
var isIndexer = prop.IsIndexer || prop.Parameters.Any();
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop);
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
}
private class PropertyFactory : CachedEntityFactory<IPropertySymbol, Property>

View File

@@ -1,3 +1,7 @@
## 1.7.60
No user-facing changes.
## 1.7.59
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.60
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.59
lastReleaseVersion: 1.7.60

View File

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

View File

@@ -1,3 +1,7 @@
## 1.7.60
No user-facing changes.
## 1.7.59
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.60
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.59
lastReleaseVersion: 1.7.60

View File

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

View File

@@ -1,3 +1,14 @@
## 5.4.8
### Minor Analysis Improvements
* C# 14: Added support for partial events.
* C# 14: Added support for the `field` keyword in properties.
### Bug Fixes
* Fixed an issue where the body of a partial member could be extracted twice. When both a *defining* and an *implementing* declaration exist, only the *implementing* declaration is now extracted.
## 5.4.7
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 14: Added support for the `field` keyword in properties.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 14: Added support for partial events.

View File

@@ -0,0 +1,10 @@
## 5.4.8
### Minor Analysis Improvements
* C# 14: Added support for partial events.
* C# 14: Added support for the `field` keyword in properties.
### Bug Fixes
* Fixed an issue where the body of a partial member could be extracted twice. When both a *defining* and an *implementing* declaration exist, only the *implementing* declaration is now extracted.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 5.4.7
lastReleaseVersion: 5.4.8

View File

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

View File

@@ -1,3 +1,7 @@
## 1.6.3
No user-facing changes.
## 1.6.2
### Bug Fixes

View File

@@ -0,0 +1,3 @@
## 1.6.3
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.2
lastReleaseVersion: 1.6.3

View File

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

View File

@@ -0,0 +1,40 @@
models
edges
| Methods.cs:8:48:8:48 | o : Object | Methods.cs:10:16:10:16 | access to parameter o : Object | provenance | |
| Methods.cs:8:48:8:48 | o : Object | Methods.cs:10:16:10:16 | access to parameter o : Object | provenance | |
| Methods.cs:17:13:17:13 | access to local variable o : Object | Methods.cs:19:38:19:38 | access to local variable o : Object | provenance | |
| Methods.cs:17:13:17:13 | access to local variable o : Object | Methods.cs:19:38:19:38 | access to local variable o : Object | provenance | |
| Methods.cs:17:17:17:33 | call to method Source<Object> : Object | Methods.cs:17:13:17:13 | access to local variable o : Object | provenance | |
| Methods.cs:17:17:17:33 | call to method Source<Object> : Object | Methods.cs:17:13:17:13 | access to local variable o : Object | provenance | |
| Methods.cs:19:13:19:18 | access to local variable result : Object | Methods.cs:20:14:20:19 | access to local variable result | provenance | |
| Methods.cs:19:13:19:18 | access to local variable result : Object | Methods.cs:20:14:20:19 | access to local variable result | provenance | |
| Methods.cs:19:22:19:39 | call to method PartialMethod : Object | Methods.cs:19:13:19:18 | access to local variable result : Object | provenance | |
| Methods.cs:19:22:19:39 | call to method PartialMethod : Object | Methods.cs:19:13:19:18 | access to local variable result : Object | provenance | |
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:8:48:8:48 | o : Object | provenance | |
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:8:48:8:48 | o : Object | provenance | |
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:19:22:19:39 | call to method PartialMethod : Object | provenance | |
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:19:22:19:39 | call to method PartialMethod : Object | provenance | |
nodes
| Methods.cs:8:48:8:48 | o : Object | semmle.label | o : Object |
| Methods.cs:8:48:8:48 | o : Object | semmle.label | o : Object |
| Methods.cs:10:16:10:16 | access to parameter o : Object | semmle.label | access to parameter o : Object |
| Methods.cs:10:16:10:16 | access to parameter o : Object | semmle.label | access to parameter o : Object |
| Methods.cs:17:13:17:13 | access to local variable o : Object | semmle.label | access to local variable o : Object |
| Methods.cs:17:13:17:13 | access to local variable o : Object | semmle.label | access to local variable o : Object |
| Methods.cs:17:17:17:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
| Methods.cs:17:17:17:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
| Methods.cs:19:13:19:18 | access to local variable result : Object | semmle.label | access to local variable result : Object |
| Methods.cs:19:13:19:18 | access to local variable result : Object | semmle.label | access to local variable result : Object |
| Methods.cs:19:22:19:39 | call to method PartialMethod : Object | semmle.label | call to method PartialMethod : Object |
| Methods.cs:19:22:19:39 | call to method PartialMethod : Object | semmle.label | call to method PartialMethod : Object |
| Methods.cs:19:38:19:38 | access to local variable o : Object | semmle.label | access to local variable o : Object |
| Methods.cs:19:38:19:38 | access to local variable o : Object | semmle.label | access to local variable o : Object |
| Methods.cs:20:14:20:19 | access to local variable result | semmle.label | access to local variable result |
| Methods.cs:20:14:20:19 | access to local variable result | semmle.label | access to local variable result |
subpaths
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:8:48:8:48 | o : Object | Methods.cs:10:16:10:16 | access to parameter o : Object | Methods.cs:19:22:19:39 | call to method PartialMethod : Object |
| Methods.cs:19:38:19:38 | access to local variable o : Object | Methods.cs:8:48:8:48 | o : Object | Methods.cs:10:16:10:16 | access to parameter o : Object | Methods.cs:19:22:19:39 | call to method PartialMethod : Object |
testFailures
#select
| Methods.cs:20:14:20:19 | access to local variable result | Methods.cs:17:17:17:33 | call to method Source<Object> : Object | Methods.cs:20:14:20:19 | access to local variable result | $@ | Methods.cs:17:17:17:33 | call to method Source<Object> : Object | call to method Source<Object> : Object |
| Methods.cs:20:14:20:19 | access to local variable result | Methods.cs:17:17:17:33 | call to method Source<Object> : Object | Methods.cs:20:14:20:19 | access to local variable result | $@ | Methods.cs:17:17:17:33 | call to method Source<Object> : Object | call to method Source<Object> : Object |

View File

@@ -0,0 +1,12 @@
/**
* @kind path-problem
*/
import csharp
import utils.test.InlineFlowTest
import DefaultFlowTest
import PathGraph
from PathNode source, PathNode sink
where flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,26 @@
public partial class Partial
{
public partial object PartialMethod(object o);
}
public partial class Partial
{
public partial object PartialMethod(object o)
{
return o;
}
}
public class C
{
public void M()
{
var o = Source<object>(1);
var p = new Partial();
var result = p.PartialMethod(o);
Sink(result); // $ hasValueFlow=1
}
public static void Sink(object o) { }
static T Source<T>(object source) => throw null;
}

View File

@@ -1,7 +1,8 @@
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 | true |
| Partial.cs:7:17:7:23 | Method2 | false |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 | true |
| Partial.cs:19:17:19:23 | Method3 | false |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 | true |
| Partial.cs:42:17:42:23 | Method4 | false |
| Partial.cs:47:17:47:23 | Method5 | false |
| Partial.cs:7:18:7:42 | PartialMethodWithoutBody1 | true |
| Partial.cs:8:17:8:23 | Method2 | false |
| Partial.cs:19:18:19:39 | PartialMethodWithBody1 | true |
| Partial.cs:20:27:20:48 | PartialMethodWithBody2 | true |
| Partial.cs:24:17:24:23 | Method3 | false |
| Partial.cs:46:18:46:42 | PartialMethodWithoutBody2 | true |
| Partial.cs:47:17:47:23 | Method4 | false |
| Partial.cs:52:17:52:23 | Method5 | false |

View File

@@ -3,6 +3,7 @@ using System;
partial class TwoPartClass
{
partial void PartialMethodWithBody1();
public partial object PartialMethodWithBody2(object obj);
partial void PartialMethodWithoutBody1();
public void Method2() { }
// Declaring declaration.
@@ -16,6 +17,10 @@ partial class TwoPartClass
partial class TwoPartClass
{
partial void PartialMethodWithBody1() { }
public partial object PartialMethodWithBody2(object obj)
{
return obj;
}
public void Method3() { }
private object _backingField;
// Implementation declaration.

View File

@@ -1,17 +1,18 @@
| Partial.cs:3:15:3:26 | TwoPartClass |
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:22:27:22:42 | PartialProperty1 |
| Partial.cs:24:9:24:11 | get_PartialProperty1 |
| Partial.cs:25:9:25:11 | set_PartialProperty1 |
| Partial.cs:29:27:29:30 | Item |
| Partial.cs:31:9:31:11 | get_Item |
| Partial.cs:32:9:32:11 | set_Item |
| Partial.cs:36:39:36:51 | PartialEvent1 |
| Partial.cs:36:55:36:57 | add_PartialEvent1 |
| Partial.cs:36:63:36:68 | remove_PartialEvent1 |
| Partial.cs:39:15:39:33 | OnePartPartialClass |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
| Partial.cs:7:18:7:42 | PartialMethodWithoutBody1 |
| Partial.cs:17:15:17:26 | TwoPartClass |
| Partial.cs:19:18:19:39 | PartialMethodWithBody1 |
| Partial.cs:20:27:20:48 | PartialMethodWithBody2 |
| Partial.cs:27:27:27:42 | PartialProperty1 |
| Partial.cs:29:9:29:11 | get_PartialProperty1 |
| Partial.cs:30:9:30:11 | set_PartialProperty1 |
| Partial.cs:34:27:34:30 | Item |
| Partial.cs:36:9:36:11 | get_Item |
| Partial.cs:37:9:37:11 | set_Item |
| Partial.cs:41:39:41:51 | PartialEvent1 |
| Partial.cs:41:55:41:57 | add_PartialEvent1 |
| Partial.cs:41:63:41:68 | remove_PartialEvent1 |
| Partial.cs:44:15:44:33 | OnePartPartialClass |
| Partial.cs:46:18:46:42 | PartialMethodWithoutBody2 |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles |
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles |

View File

@@ -1,15 +1,17 @@
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:7:17:7:23 | Method2 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:18:18:18:39 | PartialMethodWithBody1 |
| Partial.cs:16:15:16:26 | TwoPartClass | Partial.cs:19:17:19:23 | Method3 |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:39:15:39:33 | <object initializer> |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:42:17:42:23 | Method4 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:7:18:7:42 | PartialMethodWithoutBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:8:17:8:23 | Method2 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:19:18:19:39 | PartialMethodWithBody1 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:20:27:20:48 | PartialMethodWithBody2 |
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:24:17:24:23 | Method3 |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:3:15:3:26 | <object initializer> |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:7:18:7:42 | PartialMethodWithoutBody1 |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:8:17:8:23 | Method2 |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:19:18:19:39 | PartialMethodWithBody1 |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:20:27:20:48 | PartialMethodWithBody2 |
| Partial.cs:17:15:17:26 | TwoPartClass | Partial.cs:24:17:24:23 | Method3 |
| Partial.cs:44:15:44:33 | OnePartPartialClass | Partial.cs:44:15:44:33 | <object initializer> |
| Partial.cs:44:15:44:33 | OnePartPartialClass | Partial.cs:46:18:46:42 | PartialMethodWithoutBody2 |
| Partial.cs:44:15:44:33 | OnePartPartialClass | Partial.cs:47:17:47:23 | Method4 |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |
| PartialMultipleFiles2.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | <object initializer> |

View File

@@ -1,12 +1,12 @@
| Partial.cs:24:9:24:11 | get_PartialProperty1 | true |
| Partial.cs:25:9:25:11 | set_PartialProperty1 | true |
| Partial.cs:31:9:31:11 | get_Item | true |
| Partial.cs:32:9:32:11 | set_Item | true |
| Partial.cs:36:55:36:57 | add_PartialEvent1 | true |
| Partial.cs:36:63:36:68 | remove_PartialEvent1 | true |
| Partial.cs:48:30:48:32 | get_Property | false |
| Partial.cs:48:35:48:37 | set_Property | false |
| Partial.cs:51:9:51:11 | get_Item | false |
| Partial.cs:52:9:52:11 | set_Item | false |
| Partial.cs:54:31:54:35 | add_Event | false |
| Partial.cs:54:31:54:35 | remove_Event | false |
| Partial.cs:29:9:29:11 | get_PartialProperty1 | true |
| Partial.cs:30:9:30:11 | set_PartialProperty1 | true |
| Partial.cs:36:9:36:11 | get_Item | true |
| Partial.cs:37:9:37:11 | set_Item | true |
| Partial.cs:41:55:41:57 | add_PartialEvent1 | true |
| Partial.cs:41:63:41:68 | remove_PartialEvent1 | true |
| Partial.cs:53:30:53:32 | get_Property | false |
| Partial.cs:53:35:53:37 | set_Property | false |
| Partial.cs:56:9:56:11 | get_Item | false |
| Partial.cs:57:9:57:11 | set_Item | false |
| Partial.cs:59:31:59:35 | add_Event | false |
| Partial.cs:59:31:59:35 | remove_Event | false |

View File

@@ -1,4 +1,4 @@
| Partial.cs:3:15:3:26 | TwoPartClass | Partial.cs:3:15:3:26 | {...} |
| Partial.cs:39:15:39:33 | OnePartPartialClass | Partial.cs:39:15:39:33 | {...} |
| Partial.cs:45:7:45:21 | NonPartialClass | Partial.cs:45:7:45:21 | {...} |
| Partial.cs:44:15:44:33 | OnePartPartialClass | Partial.cs:44:15:44:33 | {...} |
| Partial.cs:50:7:50:21 | NonPartialClass | Partial.cs:50:7:50:21 | {...} |
| PartialMultipleFiles1.cs:1:22:1:41 | PartialMultipleFiles | PartialMultipleFiles1.cs:1:22:1:41 | {...} |

View File

@@ -1,2 +1,2 @@
| Partial.cs:36:39:36:51 | PartialEvent1 | true |
| Partial.cs:54:31:54:35 | Event | false |
| Partial.cs:41:39:41:51 | PartialEvent1 | true |
| Partial.cs:59:31:59:35 | Event | false |

View File

@@ -1,2 +1,2 @@
| Partial.cs:29:27:29:30 | Item | true |
| Partial.cs:49:19:49:22 | Item | false |
| Partial.cs:34:27:34:30 | Item | true |
| Partial.cs:54:19:54:22 | Item | false |

View File

@@ -1,3 +1,4 @@
| Partial.cs:6:18:6:42 | PartialMethodWithoutBody1 | false |
| Partial.cs:18:18:18:39 | PartialMethodWithBody1 | true |
| Partial.cs:41:18:41:42 | PartialMethodWithoutBody2 | false |
| Partial.cs:7:18:7:42 | PartialMethodWithoutBody1 | false | 0 |
| Partial.cs:19:18:19:39 | PartialMethodWithBody1 | true | 1 |
| Partial.cs:20:27:20:48 | PartialMethodWithBody2 | true | 1 |
| Partial.cs:46:18:46:42 | PartialMethodWithoutBody2 | false | 0 |

View File

@@ -4,4 +4,4 @@ private boolean hasBody(Method m) { if m.hasBody() then result = true else resul
from Method m
where m.fromSource() and m.isPartial()
select m, hasBody(m)
select m, hasBody(m), count(m.getBody())

View File

@@ -1,2 +1,2 @@
| Partial.cs:22:27:22:42 | PartialProperty1 | true |
| Partial.cs:48:19:48:26 | Property | false |
| Partial.cs:27:27:27:42 | PartialProperty1 | true |
| Partial.cs:53:19:53:26 | Property | false |

View File

@@ -1,112 +1,116 @@
Partial.cs:
# 3| [Class] TwoPartClass
# 6| 6: [Method] PartialMethodWithoutBody1
# 6| -1: [TypeMention] Void
# 7| 7: [Method] Method2
# 7| 6: [Method] PartialMethodWithoutBody1
# 7| -1: [TypeMention] Void
# 7| 4: [BlockStmt] {...}
# 18| 8: [Method] PartialMethodWithBody1
# 5| -1: [TypeMention] Void
# 18| 4: [BlockStmt] {...}
# 19| 9: [Method] Method3
# 8| 7: [Method] Method2
# 8| -1: [TypeMention] Void
# 8| 4: [BlockStmt] {...}
# 19| 8: [Method] PartialMethodWithBody1
# 19| -1: [TypeMention] Void
# 19| 4: [BlockStmt] {...}
# 20| 10: [Field] _backingField
# 20| 9: [Method] PartialMethodWithBody2
# 20| -1: [TypeMention] object
# 22| 11: [Property] PartialProperty1
# 9| -1: [TypeMention] object
# 22| -1: [TypeMention] object
# 24| 3: [Getter] get_PartialProperty1
# 24| 4: [BlockStmt] {...}
# 24| 0: [ReturnStmt] return ...;
# 24| 0: [FieldAccess] access to field _backingField
# 25| 4: [Setter] set_PartialProperty1
#-----| 2: (Parameters)
# 20| 0: [Parameter] obj
# 20| -1: [TypeMention] object
# 21| 4: [BlockStmt] {...}
# 22| 0: [ReturnStmt] return ...;
# 22| 0: [ParameterAccess] access to parameter obj
# 24| 10: [Method] Method3
# 24| -1: [TypeMention] Void
# 24| 4: [BlockStmt] {...}
# 25| 11: [Field] _backingField
# 25| -1: [TypeMention] object
# 27| 12: [Property] PartialProperty1
# 27| -1: [TypeMention] object
# 29| 3: [Getter] get_PartialProperty1
# 29| 4: [BlockStmt] {...}
# 29| 0: [ReturnStmt] return ...;
# 29| 0: [FieldAccess] access to field _backingField
# 30| 4: [Setter] set_PartialProperty1
#-----| 2: (Parameters)
# 25| 0: [Parameter] value
# 25| 4: [BlockStmt] {...}
# 25| 0: [ExprStmt] ...;
# 25| 0: [AssignExpr] ... = ...
# 25| 0: [FieldAccess] access to field _backingField
# 25| 1: [ParameterAccess] access to parameter value
# 27| 12: [Field] _backingArray
# 27| -1: [TypeMention] Object[]
# 27| 1: [TypeMention] object
# 29| 13: [Indexer] Item
# 11| -1: [TypeMention] object
# 29| -1: [TypeMention] object
# 30| 0: [Parameter] value
# 30| 4: [BlockStmt] {...}
# 30| 0: [ExprStmt] ...;
# 30| 0: [AssignExpr] ... = ...
# 30| 0: [FieldAccess] access to field _backingField
# 30| 1: [ParameterAccess] access to parameter value
# 32| 13: [Field] _backingArray
# 32| -1: [TypeMention] Object[]
# 32| 1: [TypeMention] object
# 34| 14: [Indexer] Item
# 34| -1: [TypeMention] object
#-----| 1: (Parameters)
# 11| 0: [Parameter] index
# 11| -1: [TypeMention] int
# 29| -1: [TypeMention] int
# 31| 3: [Getter] get_Item
# 34| 0: [Parameter] index
# 34| -1: [TypeMention] int
# 36| 3: [Getter] get_Item
#-----| 2: (Parameters)
# 29| 0: [Parameter] index
# 31| 4: [BlockStmt] {...}
# 31| 0: [ReturnStmt] return ...;
# 31| 0: [ArrayAccess] access to array element
# 31| -1: [FieldAccess] access to field _backingArray
# 31| 0: [ParameterAccess] access to parameter index
# 32| 4: [Setter] set_Item
#-----| 2: (Parameters)
# 29| 0: [Parameter] index
# 32| 1: [Parameter] value
# 32| 4: [BlockStmt] {...}
# 32| 0: [ExprStmt] ...;
# 32| 0: [AssignExpr] ... = ...
# 32| 0: [ArrayAccess] access to array element
# 32| -1: [FieldAccess] access to field _backingArray
# 32| 0: [ParameterAccess] access to parameter index
# 32| 1: [ParameterAccess] access to parameter value
# 36| 14: [Event] PartialEvent1
# 13| -1: [TypeMention] EventHandler
# 36| 3: [AddEventAccessor] add_PartialEvent1
#-----| 2: (Parameters)
# 36| 0: [Parameter] value
# 34| 0: [Parameter] index
# 36| 4: [BlockStmt] {...}
# 36| 4: [RemoveEventAccessor] remove_PartialEvent1
# 36| 0: [ReturnStmt] return ...;
# 36| 0: [ArrayAccess] access to array element
# 36| -1: [FieldAccess] access to field _backingArray
# 36| 0: [ParameterAccess] access to parameter index
# 37| 4: [Setter] set_Item
#-----| 2: (Parameters)
# 36| 0: [Parameter] value
# 36| 4: [BlockStmt] {...}
# 39| [Class] OnePartPartialClass
# 41| 6: [Method] PartialMethodWithoutBody2
# 41| -1: [TypeMention] Void
# 42| 7: [Method] Method4
# 42| -1: [TypeMention] Void
# 42| 4: [BlockStmt] {...}
# 45| [Class] NonPartialClass
# 47| 6: [Method] Method5
# 34| 0: [Parameter] index
# 37| 1: [Parameter] value
# 37| 4: [BlockStmt] {...}
# 37| 0: [ExprStmt] ...;
# 37| 0: [AssignExpr] ... = ...
# 37| 0: [ArrayAccess] access to array element
# 37| -1: [FieldAccess] access to field _backingArray
# 37| 0: [ParameterAccess] access to parameter index
# 37| 1: [ParameterAccess] access to parameter value
# 41| 15: [Event] PartialEvent1
# 41| 3: [AddEventAccessor] add_PartialEvent1
#-----| 2: (Parameters)
# 41| 0: [Parameter] value
# 41| 4: [BlockStmt] {...}
# 41| 4: [RemoveEventAccessor] remove_PartialEvent1
#-----| 2: (Parameters)
# 41| 0: [Parameter] value
# 41| 4: [BlockStmt] {...}
# 44| [Class] OnePartPartialClass
# 46| 6: [Method] PartialMethodWithoutBody2
# 46| -1: [TypeMention] Void
# 47| 7: [Method] Method4
# 47| -1: [TypeMention] Void
# 47| 4: [BlockStmt] {...}
# 48| 7: [Property] Property
# 48| -1: [TypeMention] object
# 48| 3: [Getter] get_Property
# 48| 4: [Setter] set_Property
# 50| [Class] NonPartialClass
# 52| 6: [Method] Method5
# 52| -1: [TypeMention] Void
# 52| 4: [BlockStmt] {...}
# 53| 7: [Property] Property
# 53| -1: [TypeMention] object
# 53| 3: [Getter] get_Property
# 53| 4: [Setter] set_Property
#-----| 2: (Parameters)
# 48| 0: [Parameter] value
# 49| 8: [Indexer] Item
# 49| -1: [TypeMention] object
# 53| 0: [Parameter] value
# 54| 8: [Indexer] Item
# 54| -1: [TypeMention] object
#-----| 1: (Parameters)
# 49| 0: [Parameter] index
# 49| -1: [TypeMention] int
# 51| 3: [Getter] get_Item
# 54| 0: [Parameter] index
# 54| -1: [TypeMention] int
# 56| 3: [Getter] get_Item
#-----| 2: (Parameters)
# 49| 0: [Parameter] index
# 51| 4: [BlockStmt] {...}
# 51| 0: [ReturnStmt] return ...;
# 51| 0: [NullLiteral] null
# 52| 4: [Setter] set_Item
# 54| 0: [Parameter] index
# 56| 4: [BlockStmt] {...}
# 56| 0: [ReturnStmt] return ...;
# 56| 0: [NullLiteral] null
# 57| 4: [Setter] set_Item
#-----| 2: (Parameters)
# 49| 0: [Parameter] index
# 52| 1: [Parameter] value
# 52| 4: [BlockStmt] {...}
# 54| 9: [Event] Event
# 54| -1: [TypeMention] EventHandler
# 54| 3: [AddEventAccessor] add_Event
# 54| 0: [Parameter] index
# 57| 1: [Parameter] value
# 57| 4: [BlockStmt] {...}
# 59| 9: [Event] Event
# 59| -1: [TypeMention] EventHandler
# 59| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 54| 0: [Parameter] value
# 54| 4: [RemoveEventAccessor] remove_Event
# 59| 0: [Parameter] value
# 59| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 54| 0: [Parameter] value
# 59| 0: [Parameter] value
PartialMultipleFiles1.cs:
# 1| [Class] PartialMultipleFiles
PartialMultipleFiles2.cs:

View File

@@ -0,0 +1,109 @@
.. _codeql-cli-2.24.2:
==========================
CodeQL 2.24.2 (2026-02-20)
==========================
.. contents:: Contents
:depth: 2
:local:
:backlinks: none
This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog <https://github.blog/tag/code-scanning/>`__, `relevant GitHub Changelog updates <https://github.blog/changelog/label/application-security/>`__, `changes in the CodeQL extension for Visual Studio Code <https://marketplace.visualstudio.com/items/GitHub.vscode-codeql/changelog>`__, and the `CodeQL Action changelog <https://github.com/github/codeql-action/blob/main/CHANGELOG.md>`__.
Security Coverage
-----------------
CodeQL 2.24.2 runs a total of 491 security queries when configured with the Default suite (covering 166 CWE). The Extended suite enables an additional 135 queries (covering 35 more CWE).
CodeQL CLI
----------
Bug Fixes
~~~~~~~~~
* Fixed SARIF output to generate RFC 1738 compatible file URIs. File URIs now always use the :code:`file:///` format instead of :code:`file:/` for better interoperability with SARIF consumers.
Query Packs
-----------
Bug Fixes
~~~~~~~~~
C#
""
* The :code:`cs/web/missing-token-validation` ("Missing cross-site request forgery token validation") query now recognizes antiforgery attributes on base controller classes, fixing false positives when :code:`[ValidateAntiForgeryToken]` or :code:`[AutoValidateAntiforgeryToken]` is applied to a parent class.
Language Libraries
------------------
Bug Fixes
~~~~~~~~~
Python
""""""
* Using :code:`=` as a fill character in a format specifier (e.g. :code:`f"{x:=^20}"`) now no longer results in a syntax error during parsing.
Breaking Changes
~~~~~~~~~~~~~~~~
Golang
""""""
* The :code:`BasicBlock` class is now defined using the shared basic blocks library. :code:`BasicBlock.getRoot` has been replaced by :code:`BasicBlock.getScope`. :code:`BasicBlock.getAPredecessor` and :code:`BasicBlock.getASuccessor` now take a :code:`SuccessorType` argument. :code:`ReachableJoinBlock.inDominanceFrontierOf` has been removed, so use :code:`BasicBlock.inDominanceFrontier` instead, swapping the receiver and the argument.
Major Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Golang
""""""
* Go 1.26 is now supported.
Minor Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
C/C++
"""""
* Added remote flow source models for the :code:`winhttp.h` windows header and the Azure SDK core library for C/C++.
C#
""
* The model for :code:`System.Web.HttpUtility` has been modified to better model the flow of tainted URIs.
* C# 14: Added support for :code:`extension` members in the extractor, QL library, data flow, and Models as Data, covering extension methods, properties, and operators.
Java/Kotlin
"""""""""""
* Using a regular expression to check that a string doesn't contain any line breaks is already a sanitizer for :code:`java/log-injection`. Additional ways of doing the regular expression check are now recognised, including annotation with :code:`@javax.validation.constraints.Pattern`.
* More ways of checking that a string matches a regular expression are now considered as sanitizers for various queries, including :code:`java/ssrf` and :code:`java/path-injection`. In particular, being annotated with :code:`@javax.validation.constraints.Pattern` is now recognised as a sanitizer for those queries.
* Kotlin versions up to 2.3.10 are now supported.
Python
""""""
* Added request forgery sink models for the Azure SDK.
* Made it so that models-as-data sinks with the kind :code:`request-forgery` contribute to the class :code:`Http::Client::Request` which represents HTTP client requests.
Deprecated APIs
~~~~~~~~~~~~~~~
Java/Kotlin
"""""""""""
* The :code:`UnreachableBlocks.qll` library has been deprecated.
* Renamed the following predicates to increase uniformity across languages. The :code:`getBody` predicate already existed on :code:`LoopStmt`, but is now properly inherited.
* :code:`UnaryExpr.getExpr` to :code:`getOperand`.
* :code:`ConditionalExpr.getTrueExpr` to :code:`getThen`.
* :code:`ConditionalExpr.getFalseExpr` to :code:`getElse`.
* :code:`ReturnStmt.getResult` to :code:`getExpr`.
* :code:`WhileStmt.getStmt` to :code:`getBody`.
* :code:`DoStmt.getStmt` to :code:`getBody`.
* :code:`ForStmt.getStmt` to :code:`getBody`.
* :code:`EnhancedForStmt.getStmt` to :code:`getBody`.

View File

@@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here <https://docs.g
.. toctree::
:maxdepth: 1
codeql-cli-2.24.2
codeql-cli-2.24.1
codeql-cli-2.24.0
codeql-cli-2.23.9

View File

@@ -1,4 +1,5 @@
load("@rules_go//go:def.bzl", "go_library")
load("@rules_java//java:defs.bzl", "java_library")
load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
# gazelle:prefix github.com/github/codeql-go/extractor

View File

@@ -1,3 +1,7 @@
## 1.0.43
No user-facing changes.
## 1.0.42
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.0.43
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.0.42
lastReleaseVersion: 1.0.43

View File

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

View File

@@ -1,3 +1,7 @@
## 7.0.1
No user-facing changes.
## 7.0.0
### Breaking Changes

View File

@@ -0,0 +1,3 @@
## 7.0.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.0.0
lastReleaseVersion: 7.0.1

View File

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

View File

@@ -1,3 +1,7 @@
## 1.5.7
No user-facing changes.
## 1.5.6
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.5.7
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.5.6
lastReleaseVersion: 1.5.7

View File

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

View File

@@ -1,3 +1,9 @@
## 8.1.1
### Minor Analysis Improvements
* Some modelling which previously only worked for Java EE packages beginning with "javax" will now also work for Java EE packages beginning with "jakarta" as well. This may lead to some alert changes.
## 8.1.0
### Deprecated APIs

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 8.1.1
### Minor Analysis Improvements
* Some modelling which previously only worked for Java EE packages beginning with "javax" will now also work for Java EE packages beginning with "jakarta" as well. This may lead to some alert changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 8.1.0
lastReleaseVersion: 8.1.1

View File

@@ -27,9 +27,9 @@ module JCAModel {
predicate cipher_names(string algo) {
algo.toUpperCase()
.matches([
"AES", "AESWrap", "AESWrapPad", "ARCFOUR", "ARIA", "Blowfish", "Camellia", "ChaCha20",
"ChaCha20-Poly1305", "DES", "DESede", "DESedeWrap", "ECIES", "PBEWith%", "RC2", "RC4",
"RC5", "RSA", "Salsa20", "SEED", "Skipjack", "Idea", "Twofish"
"AES", "AESWrap", "AESWrapPad", "ARCFOUR", "Blowfish", "ChaCha20", "ChaCha20-Poly1305",
"DES", "DESede", "DESedeWrap", "ECIES", "PBEWith%", "RC2", "RC4", "RC5", "RSA",
"Skipjack", "Idea"
].toUpperCase())
}
@@ -106,7 +106,7 @@ module JCAModel {
bindingset[name]
predicate key_agreement_names(string name) {
name.toUpperCase()
.matches(["DH", "EDH", "ECDH", "ECMQV", "X25519", "X448", "ML-KEM%", "XDH"].toUpperCase())
.matches(["DH", "EDH", "ECDH", "X25519", "X448", "ML-KEM%", "XDH"].toUpperCase())
}
bindingset[name]
@@ -189,8 +189,6 @@ module JCAModel {
type = KeyOpAlg::PCBC() and name = "PCBC"
or
type = KeyOpAlg::KWP() and name = "KWP"
or
type = KeyOpAlg::LRW() and name = "LRW"
}
bindingset[name]
@@ -199,32 +197,13 @@ module JCAModel {
upper.matches("AES%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
or
// NOTE: DESede (TripleDES) must be matched before DES% to avoid misclassification
upper.matches("DESEDE%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
or
not upper.matches("DESEDE%") and
// NOTE: there is DES and DESede
upper.matches("DES%") and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::DES())
or
upper = "TRIPLEDES" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TRIPLE_DES())
or
upper = "ARIA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::ARIA())
or
upper = "CAMELLIA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::CAMELLIA())
or
upper = "TWOFISH" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::TWOFISH())
or
upper = "SEED" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::SEED())
or
upper = "SALSA20" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::SALSA20())
or
upper = "IDEA" and
type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::IDEA())
or
@@ -265,9 +244,6 @@ module JCAModel {
type = Crypto::ECDH() and
name.toUpperCase() in ["ECDH", "X25519", "X448", "XDH"]
or
type = Crypto::ECMQV() and
name.toUpperCase() = "ECMQV"
or
type = Crypto::OtherKeyAgreementType() and
name.toUpperCase().matches("ML-KEM%")
}
@@ -387,10 +363,6 @@ module JCAModel {
type instanceof KeyOpAlg::PKCS7 and name = ["PKCS5Padding", "PKCS7Padding"] // TODO: misnomer in the JCA?
or
type instanceof KeyOpAlg::OAEP and name.matches("OAEP%") // TODO: handle OAEPWith%
or
type instanceof KeyOpAlg::PKCS1_V1_5 and name = "PKCS1Padding"
or
type instanceof KeyOpAlg::PSS and name = "PSS"
}
override KeyOpAlg::PaddingSchemeType getPaddingType() {
@@ -634,7 +606,7 @@ module JCAModel {
}
predicate isBarrier(DataFlow::Node node, FlowState state) {
exists(Init call | node.asExpr() = call.(MethodCall).getQualifier() |
exists(CipherInitCall call | node.asExpr() = call.getQualifier() |
state instanceof UninitializedFlowState
or
state.(InitializedFlowState).getInitCall() != call
@@ -1879,14 +1851,7 @@ module JCAModel {
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { result = this }
override predicate shouldHaveModeOfOperation() { none() }
override predicate shouldHavePaddingScheme() {
// Only RSA-based signatures have a meaningful padding concept (PSS or PKCS1v1.5)
signature_name_to_type_known(KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA()), super.getValue())
}
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
}
class SignatureHashAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof SignatureStringLiteralAlgorithmInstance
@@ -1905,185 +1870,6 @@ module JCAModel {
override int getFixedDigestLength() { result = digestLength }
}
/**
* Determines if a signature algorithm name implies PSS padding.
*/
bindingset[name]
private predicate signatureImpliesPss(string name) {
name.toUpperCase().matches("%RSASSA-PSS%") or
name.toUpperCase().matches("%WITHRSA%MGF1%") or
name.toUpperCase().matches("%WITHRSA/PSS%")
}
/**
* Base class for PSS padding derived from signature algorithm names.
* Provides getPaddingType() on PaddingAlgorithmInstance to break the non-monotonic
* recursion that would occur if the derived PssPaddingAlgorithmInstance class
* defined getPaddingType() itself (since PssPaddingAlgorithmInstance's charpred
* calls getPaddingType()).
* Follows the same two-class pattern used for OAEP:
* CipherStringLiteralPaddingAlgorithmInstance → OaepPaddingAlgorithmInstance.
*/
private class SignaturePssPaddingBase extends SignatureStringLiteralAlgorithmInstance,
Crypto::PaddingAlgorithmInstance instanceof SignatureStringLiteral
{
SignaturePssPaddingBase() { signatureImpliesPss(super.getValue()) }
override string getRawPaddingAlgorithmName() { result = "PSS" }
override KeyOpAlg::PaddingSchemeType getPaddingType() { result instanceof KeyOpAlg::PSS }
}
/**
* A PSS padding algorithm instance derived from a signature algorithm literal.
* Extends PssPaddingAlgorithmInstance (whose charpred evaluates through
* SignaturePssPaddingBase.getPaddingType()) to produce MD and MGF1Hash edges.
*
* For name-implied PSS (e.g., "SHA256withRSAandMGF1"), the same literal element
* is also a SignatureHashAlgorithmInstance, so `result = this` yields the hash.
* For bare "RSASSA-PSS", `result = this` has no result (this is not a
* HashAlgorithmInstance), so the graph falls back to self-referencing (unknown).
* When a PSSParameterSpec is connected via setParameter(), the explicit hash
* from the spec is used instead.
*/
class SignaturePssPaddingAlgorithmInstance extends Crypto::PssPaddingAlgorithmInstance,
SignaturePssPaddingBase instanceof SignatureStringLiteral
{
override Crypto::HashAlgorithmInstance getHashAlgorithm() {
// Name-implied hash (e.g., SHA256withRSAandMGF1 → SHA-256)
result = this
or
// Explicit PSS hash from PSSParameterSpec via Signature.setParameter()
exists(PssParameterSpecInstantiation spec |
pssSpecForSignatureLiteral(spec, this) and
result.(PssParameterSpecDigestHashAlgorithmInstance).getSpec() = spec
)
}
override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() {
// Name-implied MGF1 hash (defaults to same hash as digest)
result = this
or
// Explicit MGF1 hash from PSSParameterSpec via Signature.setParameter()
exists(PssParameterSpecInstantiation spec |
pssSpecForSignatureLiteral(spec, this) and
result.(PssParameterSpecMgf1HashAlgorithmInstance).getSpec() = spec
)
}
}
/**
* A PSSParameterSpec instantiation, e.g.,
* new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1)
*/
class PssParameterSpecInstantiation extends ClassInstanceExpr {
PssParameterSpecInstantiation() {
this.getConstructedType().hasQualifiedName("java.security.spec", "PSSParameterSpec")
}
/** Gets the digest algorithm name argument (arg 0). */
Expr getDigestAlgorithmArg() { result = this.getArgument(0) }
/** Gets the MGF algorithm name argument (arg 1). */
Expr getMgfAlgorithmArg() { result = this.getArgument(1) }
/** Gets the salt length argument (arg 3). */
Expr getSaltLengthArg() { result = this.getArgument(3) }
/** Gets the MGF parameter spec argument (arg 2), e.g., MGF1ParameterSpec.SHA256. */
Expr getMgfSpecArg() { result = this.getArgument(2) }
}
/**
* A static field access on `java.security.spec.MGF1ParameterSpec`, e.g.,
* `MGF1ParameterSpec.SHA256`. These fields represent well-known MGF1 hash
* algorithm configurations.
*/
class Mgf1ParameterSpecFieldAccess extends FieldAccess {
Mgf1ParameterSpecFieldAccess() {
this.getField().getDeclaringType().hasQualifiedName("java.security.spec", "MGF1ParameterSpec") and
this.getField().isStatic()
}
/** Gets the hash algorithm name corresponding to this MGF1 field. */
string getHashAlgorithmName() {
this.getField().getName() = "SHA1" and result = "SHA-1"
or
this.getField().getName() = "SHA224" and result = "SHA-224"
or
this.getField().getName() = "SHA256" and result = "SHA-256"
or
this.getField().getName() = "SHA384" and result = "SHA-384"
or
this.getField().getName() = "SHA512" and result = "SHA-512"
or
this.getField().getName() = "SHA512_224" and result = "SHA-512/224"
or
this.getField().getName() = "SHA512_256" and result = "SHA-512/256"
}
}
/**
* A hash algorithm instance for the digest algorithm argument (arg 0) of a
* PSSParameterSpec instantiation, e.g., "SHA-256" in:
* new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1)
*
* Type resolution delegates to hash_name_to_type_known from Standardization.
*/
class PssParameterSpecDigestHashAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof JavaConstant
{
PssParameterSpecInstantiation spec;
PssParameterSpecDigestHashAlgorithmInstance() {
this = spec.getDigestAlgorithmArg() and
// Only instantiate when the value resolves to a known hash type
exists(hash_name_to_type_known(super.getValue(), _))
}
/** Gets the PSSParameterSpec this digest hash belongs to. */
PssParameterSpecInstantiation getSpec() { result = spec }
override string getRawHashAlgorithmName() { result = super.getValue() }
override Crypto::THashType getHashType() {
result = hash_name_to_type_known(super.getValue(), _)
}
override int getFixedDigestLength() {
exists(hash_name_to_type_known(super.getValue(), result))
}
}
/**
* A hash algorithm instance for the MGF1 parameter spec argument (arg 2) of a
* PSSParameterSpec instantiation, e.g., MGF1ParameterSpec.SHA256 in:
* new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1)
*
* The field name is normalized to a standard hash algorithm name (e.g.,
* SHA256 -> SHA-256), then type resolution delegates to hash_name_to_type_known.
*/
class PssParameterSpecMgf1HashAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof Mgf1ParameterSpecFieldAccess
{
PssParameterSpecInstantiation spec;
string normalizedName;
PssParameterSpecMgf1HashAlgorithmInstance() {
this = spec.getMgfSpecArg() and
normalizedName = super.getHashAlgorithmName() and
// Only instantiate when the normalized name resolves to a known hash type
exists(hash_name_to_type_known(normalizedName, _))
}
/** Gets the PSSParameterSpec this MGF1 hash belongs to. */
PssParameterSpecInstantiation getSpec() { result = spec }
override string getRawHashAlgorithmName() { result = super.getField().getName() }
override Crypto::THashType getHashType() { result = hash_name_to_type_known(normalizedName, _) }
override int getFixedDigestLength() { exists(hash_name_to_type_known(normalizedName, result)) }
}
class SignatureInitCall extends MethodCall {
SignatureInitCall() {
this.getCallee().hasQualifiedName("java.security", "Signature", ["initSign", "initVerify"])
@@ -2095,23 +1881,6 @@ module JCAModel {
}
}
/**
* A call to `Signature.setParameter(AlgorithmParameterSpec)`, used to
* configure algorithm parameters such as PSSParameterSpec on a Signature instance.
*/
class SignatureSetParameterCall extends MethodCall {
SignatureSetParameterCall() {
this.getMethod().hasQualifiedName("java.security", "Signature", "setParameter") and
this.getMethod()
.getParameterType(0)
.(RefType)
.hasQualifiedName("java.security.spec", "AlgorithmParameterSpec")
}
/** Gets the AlgorithmParameterSpec argument. */
Expr getParameterSpecArg() { result = this.getArgument(0) }
}
class SignatureOperationCall extends MethodCall {
SignatureOperationCall() {
this.getMethod().hasQualifiedName("java.security", "Signature", ["update", "sign", "verify"])
@@ -2176,6 +1945,7 @@ module JCAModel {
}
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
// TODO: RSASSA-PSS literal sets hashes differently, through a ParameterSpec
result = this.getInstantiationCall().getAlgorithmArg()
}
@@ -2202,58 +1972,6 @@ module JCAModel {
GetInstanceInitUseFlowAnalysis<SignatureGetInstanceCall, SignatureInitCall,
SignatureOperationCall>;
/**
* Flow from `Signature.getInstance()` return value to `Signature.setParameter()` qualifier.
* Used to connect a signature algorithm literal to its PSSParameterSpec configuration.
*/
module SignatureToSetParameterConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SignatureGetInstanceCall }
predicate isSink(DataFlow::Node sink) {
exists(SignatureSetParameterCall c | sink.asExpr() = c.getQualifier())
}
}
module SignatureToSetParameterFlow = DataFlow::Global<SignatureToSetParameterConfig>;
/**
* Flow from `PSSParameterSpec` instantiation to `Signature.setParameter()` argument.
*/
module PssSpecToSetParameterConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof PssParameterSpecInstantiation }
predicate isSink(DataFlow::Node sink) {
exists(SignatureSetParameterCall c | sink.asExpr() = c.getParameterSpecArg())
}
}
module PssSpecToSetParameterFlow = DataFlow::Global<PssSpecToSetParameterConfig>;
/**
* Connects a PSSParameterSpec instantiation to the signature PSS padding literal
* for which it provides configuration, via `Signature.setParameter()`.
*
* The connection requires:
* 1. The padding literal flows (via its consumer) to a `Signature.getInstance()` call
* 2. That getInstance call flows to a `Signature.setParameter()` qualifier
* 3. The PSSParameterSpec flows to the same setParameter's argument
*/
private predicate pssSpecForSignatureLiteral(
PssParameterSpecInstantiation spec, SignaturePssPaddingAlgorithmInstance literal
) {
exists(
SignatureSetParameterCall setParam, SignatureGetInstanceCall getInstance,
SignatureGetInstanceAlgorithmValueConsumer consumer
|
consumer = literal.getConsumer() and
consumer = getInstance.getAlgorithmArg() and
SignatureToSetParameterFlow::flow(DataFlow::exprNode(getInstance),
DataFlow::exprNode(setParam.getQualifier())) and
PssSpecToSetParameterFlow::flow(DataFlow::exprNode(spec),
DataFlow::exprNode(setParam.getParameterSpecArg()))
)
}
/*
* Elliptic Curves (EC)
*/

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 8.1.1-dev
version: 8.1.1
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -1,3 +1,10 @@
## 1.10.8
### Minor Analysis Improvements
* The Java extractor and QL libraries now support Java 26.
* Java analysis now selects the Java version to use informed by Maven POM files across all project modules. It also tries to use Java 17 or higher for all Maven projects if possible, for improved build compatibility.
## 1.10.7
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The Java extractor and QL libraries now support Java 26.

View File

@@ -1,4 +1,6 @@
---
category: minorAnalysis
---
* Java analysis now selects the Java version to use informed by Maven POM files across all project modules. It also tries to use Java 17 or higher for all Maven projects if possible, for improved build compatibility.
## 1.10.8
### Minor Analysis Improvements
* The Java extractor and QL libraries now support Java 26.
* Java analysis now selects the Java version to use informed by Maven POM files across all project modules. It also tries to use Java 17 or higher for all Maven projects if possible, for improved build compatibility.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.10.7
lastReleaseVersion: 1.10.8

View File

@@ -1,119 +0,0 @@
/**
* @name All cryptographic classifications
* @description Reports every cryptographic element classified as quantum-vulnerable, insecure, or secure
* using all predicates in the QuantumCryptoClassification library.
* @id java/quantum/examples/demo/all-classifications
* @kind problem
* @problem.severity warning
* @tags quantum
* experimental
*/
import QuantumCryptoClassification
/**
* Gets a short label for logical grouping of each finding category.
*/
string categoryLabel(string cat) {
cat = "Algorithm" and result = "Algorithm"
or
cat = "KeyAgreement" and result = "KeyAgreement"
or
cat = "Curve" and result = "Curve"
or
cat = "Padding" and result = "Padding"
or
cat = "Mode" and result = "Mode"
or
cat = "Hash" and result = "Hash"
or
cat = "KeySize" and result = "KeySize"
}
from Crypto::NodeBase node, string category, string classification, string detail
where
// ---- Key-operation algorithms (quantum-vulnerable / insecure / secure) ----
exists(Crypto::KeyOperationAlgorithmNode alg |
node = alg and
category = "Algorithm" and
classification = classifyAlgorithmType(alg.getAlgorithmType()) and
classification != "other" and
detail = alg.getAlgorithmName()
)
or
// ---- Key-agreement algorithms (quantum-vulnerable) ----
exists(Crypto::KeyAgreementAlgorithmNode kaAlg |
node = kaAlg and
category = "KeyAgreement" and
classification = classifyKeyAgreementType(kaAlg.getKeyAgreementType()) and
classification != "other" and
detail = kaAlg.getAlgorithmName()
)
or
// ---- Elliptic curves (quantum-vulnerable) ----
exists(Crypto::EllipticCurveNode curve |
node = curve and
category = "Curve" and
isQuantumVulnerableCurveType(curve.getEllipticCurveType()) and
classification = "quantum-vulnerable" and
detail = curve.getAlgorithmName() + " (" + curve.getEllipticCurveType().toString() + ")"
)
or
// ---- Padding (quantum-vulnerable) ----
exists(Crypto::PaddingAlgorithmNode pad |
node = pad and
category = "Padding" and
isQuantumVulnerablePaddingType(pad.getPaddingType()) and
classification = "quantum-vulnerable" and
detail = pad.getPaddingType().toString()
)
or
// ---- Block modes (insecure) ----
exists(Crypto::ModeOfOperationAlgorithmNode mode |
node = mode and
category = "Mode" and
isInsecureModeType(mode.getModeType()) and
classification = "insecure" and
detail = mode.getModeType().toString()
)
or
// ---- Hash algorithms (insecure / secure) ----
exists(Crypto::HashAlgorithmNode hash |
node = hash and
category = "Hash" and
(
isInsecureHashType(hash.getHashType()) and
classification = "insecure" and
detail = hash.getHashType().toString()
or
isSecureHashType(hash.getHashType()) and
classification = "secure" and
detail =
hash.getHashType().toString() +
any(string s |
if exists(hash.getDigestLength())
then s = " (" + hash.getDigestLength().toString() + "-bit)"
else s = ""
)
)
)
or
// ---- Key sizes with quantum-vulnerable algorithms ----
exists(Crypto::KeyCreationOperationNode keygen, Crypto::AlgorithmNode alg, int keySize |
node = keygen and
category = "KeySize" and
classification = "quantum-vulnerable" and
alg = keygen.getAKnownAlgorithm() and
keygen.getAKeySizeSource().asElement().(Literal).getValue().toInt() = keySize and
(
exists(Crypto::KeyOperationAlgorithmNode keyAlg |
keyAlg = alg and isQuantumVulnerableAlgorithmType(keyAlg.getAlgorithmType())
)
or
exists(Crypto::KeyAgreementAlgorithmNode kaAlg |
kaAlg = alg and isQuantumVulnerableKeyAgreementType(kaAlg.getKeyAgreementType())
)
) and
detail = keySize.toString() + "-bit key for " + alg.getAlgorithmName()
)
select node, "[" + classification + "] " + categoryLabel(category) + ": " + detail

View File

@@ -1,17 +0,0 @@
/**
* @name Insecure block mode
* @description Detects use of insecure block cipher modes of operation.
* @id java/quantum/examples/demo/insecure-block-mode
* @kind problem
* @problem.severity error
* @tags quantum
* experimental
*/
import QuantumCryptoClassification
from Crypto::KeyOperationAlgorithmNode alg, Crypto::ModeOfOperationAlgorithmNode mode
where
mode = alg.getModeOfOperation() and
isInsecureModeType(mode.getModeType())
select alg, "Insecure block mode $@ detected.", mode, mode.getModeType().toString()

View File

@@ -1,18 +0,0 @@
/**
* @name Insecure symmetric cipher
* @description Detects use of classically insecure symmetric cipher algorithms.
* @id java/quantum/examples/demo/insecure-cipher
* @kind problem
* @problem.severity error
* @tags external/cwe/cwe-327
* quantum
* experimental
*/
import QuantumCryptoClassification
from Crypto::KeyOperationAlgorithmNode alg, KeyOpAlg::TSymmetricCipherType cipherType
where
alg.getAlgorithmType() = KeyOpAlg::TSymmetricCipher(cipherType) and
isInsecureCipherType(cipherType)
select alg, "Insecure symmetric cipher: " + alg.getAlgorithmName() + "."

View File

@@ -1,16 +0,0 @@
/**
* @name Insecure hash algorithm
* @description Detects use of classically insecure hash algorithms.
* @id java/quantum/examples/demo/insecure-hash
* @kind problem
* @problem.severity error
* @tags external/cwe/cwe-327
* quantum
* experimental
*/
import QuantumCryptoClassification
from Crypto::HashAlgorithmNode alg
where isInsecureHashType(alg.getHashType())
select alg, "Insecure hash algorithm: " + alg.getHashType().toString() + "."

View File

@@ -1,26 +0,0 @@
/**
* @name Inventory of cryptographic algorithms
* @description Lists all detected key operation algorithms with their security classification.
* @id java/quantum/examples/demo/inventory-algorithms
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import QuantumCryptoClassification
from Crypto::AlgorithmNode alg, string name, string classification
where
exists(Crypto::KeyOperationAlgorithmNode keyAlg |
keyAlg = alg and
name = keyAlg.getAlgorithmName() and
classification = classifyAlgorithmType(keyAlg.getAlgorithmType())
)
or
exists(Crypto::KeyAgreementAlgorithmNode kaAlg |
kaAlg = alg and
name = kaAlg.getAlgorithmName() and
classification = classifyKeyAgreementType(kaAlg.getKeyAgreementType())
)
select alg, "Algorithm: " + name + " [" + classification + "]."

View File

@@ -1,27 +0,0 @@
/**
* @name Inventory of elliptic curves
* @description Lists all detected elliptic curve algorithms with their family and key size.
* @id java/quantum/examples/demo/inventory-curves
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import experimental.quantum.Language
from Crypto::EllipticCurveNode c, string detail
where
if c.properties("KeySize", _, _)
then
exists(string ks |
c.properties("KeySize", ks, _) and
detail =
"Elliptic curve: " + c.getAlgorithmName() + " (" + c.getEllipticCurveType().toString() +
" family, " + ks + "-bit)."
)
else
detail =
"Elliptic curve: " + c.getAlgorithmName() + " (" + c.getEllipticCurveType().toString() +
" family)."
select c, detail

View File

@@ -1,21 +0,0 @@
/**
* @name Inventory of hash algorithms
* @description Lists all detected hash algorithms with their digest length.
* @id java/quantum/examples/demo/inventory-hashes
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import experimental.quantum.Language
from Crypto::HashAlgorithmNode h, string detail
where
if exists(h.getDigestLength())
then
detail =
"Hash algorithm: " + h.getHashType().toString() + " (" + h.getDigestLength().toString() +
"-bit digest)."
else detail = "Hash algorithm: " + h.getHashType().toString() + "."
select h, detail

View File

@@ -1,18 +0,0 @@
/**
* @name Inventory of cryptographic key sizes
* @description Lists all detected key creation operations with their algorithm and key size.
* @id java/quantum/examples/demo/inventory-key-sizes
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import experimental.quantum.Language
from Crypto::KeyCreationOperationNode keygen, Crypto::AlgorithmNode alg, int keySize
where
alg = keygen.getAKnownAlgorithm() and
keygen.getAKeySizeSource().asElement().(Literal).getValue().toInt() = keySize
select keygen, "Key creation with algorithm $@ using " + keySize.toString() + "-bit key.", alg,
alg.getAlgorithmName()

View File

@@ -1,14 +0,0 @@
/**
* @name Inventory of block cipher modes
* @description Lists all detected modes of operation for block ciphers.
* @id java/quantum/examples/demo/inventory-modes
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import experimental.quantum.Language
from Crypto::ModeOfOperationAlgorithmNode m
select m, "Mode of operation: " + m.getModeType().toString() + "."

View File

@@ -1,14 +0,0 @@
/**
* @name Inventory of padding schemes
* @description Lists all detected padding scheme algorithms.
* @id java/quantum/examples/demo/inventory-padding
* @kind problem
* @problem.severity recommendation
* @tags quantum
* experimental
*/
import experimental.quantum.Language
from Crypto::PaddingAlgorithmNode pad
select pad, "Padding scheme: " + pad.getPaddingType().toString() + "."

View File

@@ -1,32 +0,0 @@
/**
* @name JWS PS protocol detected (PS256/PS384/PS512)
* @description Detects RSA-PSS signature with SHA-2 hash, corresponding to JWS PS256/PS384/PS512.
* @id java/quantum/examples/demo/protocol-jws-ps
* @kind problem
* @problem.severity warning
* @tags quantum
* experimental
*/
import experimental.quantum.Language
import Crypto::KeyOpAlg as KeyOpAlg
from
Crypto::SignatureOperationNode sigOp, Crypto::KeyOperationAlgorithmNode alg,
Crypto::PssPaddingAlgorithmNode pss, Crypto::HashAlgorithmNode hash, int digestLen
where
alg = sigOp.getAKnownAlgorithm() and
alg.getAlgorithmType() = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA()) and
pss = alg.getPaddingAlgorithm() and
// Get hash from the PSS padding or from the signature operation
(
hash = pss.getPssHashAlgorithm()
or
hash = sigOp.getHashAlgorithm() and not exists(pss.getPssHashAlgorithm())
) and
hash.getHashType() = Crypto::SHA2() and
digestLen = hash.getDigestLength() and
digestLen in [256, 384, 512]
select alg,
"JWS PS" + digestLen.toString() + " protocol detected (RSA-PSS + SHA-" + digestLen.toString() +
")."

View File

@@ -1,29 +0,0 @@
/**
* @name JWS RS protocol detected (RS256/RS384/RS512)
* @description Detects RSA PKCS#1 v1.5 signature with SHA-2 hash, corresponding to JWS RS256/RS384/RS512.
* @id java/quantum/examples/demo/protocol-jws-rs
* @kind problem
* @problem.severity warning
* @tags quantum
* experimental
*/
import experimental.quantum.Language
import Crypto::KeyOpAlg as KeyOpAlg
from
Crypto::SignatureOperationNode sigOp, Crypto::KeyOperationAlgorithmNode alg,
Crypto::HashAlgorithmNode hash, int digestLen
where
alg = sigOp.getAKnownAlgorithm() and
alg.getAlgorithmType() = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA()) and
// No PSS padding — implies PKCS#1 v1.5
not alg.getPaddingAlgorithm() instanceof Crypto::PssPaddingAlgorithmNode and
// Hash is SHA-2 with standard JWS digest lengths
hash = sigOp.getHashAlgorithm() and
hash.getHashType() = Crypto::SHA2() and
digestLen = hash.getDigestLength() and
digestLen in [256, 384, 512]
select alg,
"JWS RS" + digestLen.toString() + " protocol detected (RSA PKCS#1 v1.5 + SHA-" +
digestLen.toString() + ")."

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