mirror of
https://github.com/github/codeql.git
synced 2026-05-18 05:07:06 +02:00
Compare commits
95 Commits
nicolaswil
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d30e3ca5e | ||
|
|
df7379c0d2 | ||
|
|
7795badd18 | ||
|
|
600f585a31 | ||
|
|
4280d35bf3 | ||
|
|
11a726d1b4 | ||
|
|
89e5a9bd72 | ||
|
|
cfbae50845 | ||
|
|
9b9c9304c7 | ||
|
|
c4f8748a42 | ||
|
|
5523b5e25f | ||
|
|
4e4d0555c0 | ||
|
|
ccc318106e | ||
|
|
4d0c72eafe | ||
|
|
15a2575949 | ||
|
|
968856ed96 | ||
|
|
5b5dc9c708 | ||
|
|
42e41c57d4 | ||
|
|
f0e665d08c | ||
|
|
de9b1adf63 | ||
|
|
018674cfde | ||
|
|
266130b5cf | ||
|
|
8769059ce5 | ||
|
|
6bfb1e1fae | ||
|
|
f107235db2 | ||
|
|
3e2f6e571f | ||
|
|
ea9e4b3409 | ||
|
|
d36350aca4 | ||
|
|
0947323e78 | ||
|
|
15af6c1b20 | ||
|
|
f9869daa91 | ||
|
|
61d809b41a | ||
|
|
197ee9b9a6 | ||
|
|
7df44f9418 | ||
|
|
7351e82c92 | ||
|
|
8488039fb9 | ||
|
|
7de476aeb0 | ||
|
|
a255b4f50f | ||
|
|
003b539287 | ||
|
|
03a54bfbf9 | ||
|
|
d3fcc2a6cc | ||
|
|
e8427a59f5 | ||
|
|
e9511560b7 | ||
|
|
6b7f339287 | ||
|
|
0151e8427c | ||
|
|
e14b4f1c5c | ||
|
|
365bae1f9c | ||
|
|
79ac95d8a8 | ||
|
|
8719072519 | ||
|
|
af0bfe0981 | ||
|
|
d546b85163 | ||
|
|
2969feef89 | ||
|
|
9773775a08 | ||
|
|
532e1feacc | ||
|
|
7d7bbf2a50 | ||
|
|
0e543a9843 | ||
|
|
a83c53ec9a | ||
|
|
ada9c452f0 | ||
|
|
99de5d4238 | ||
|
|
12bd709219 | ||
|
|
a935d97190 | ||
|
|
27638c7029 | ||
|
|
07099f17d6 | ||
|
|
e8de8433f4 | ||
|
|
20fea3955e | ||
|
|
a684943bb7 | ||
|
|
a0099d64c8 | ||
|
|
1d6b8c5120 | ||
|
|
05d681fe19 | ||
|
|
f577e973bc | ||
|
|
1bff7a3eb8 | ||
|
|
eb7f1989c7 | ||
|
|
de5470a85c | ||
|
|
b3681f7a0c | ||
|
|
6294c3b3b8 | ||
|
|
4aee99f0eb | ||
|
|
5df695bec9 | ||
|
|
1fa183ee2a | ||
|
|
d4bb92b038 | ||
|
|
3e4f42f8a3 | ||
|
|
fc429c1757 | ||
|
|
1d7a39a093 | ||
|
|
05f9b4124d | ||
|
|
b8f9dd9de5 | ||
|
|
3dc465f167 | ||
|
|
61e8f91404 | ||
|
|
e587541e55 | ||
|
|
8a051d7e57 | ||
|
|
a5aeadd31d | ||
|
|
08174d7ec9 | ||
|
|
05a487ec3b | ||
|
|
c0a5c63e8e | ||
|
|
9de5f5c72b | ||
|
|
d40071321a | ||
|
|
97f7dcb04a |
@@ -1,3 +1,7 @@
|
||||
## 0.4.29
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.28
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/lib/change-notes/released/0.4.29.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.29.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.29
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.28
|
||||
lastReleaseVersion: 0.4.29
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.29-dev
|
||||
version: 0.4.29
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.6.21
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.20
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.21.md
Normal file
3
actions/ql/src/change-notes/released/0.6.21.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.21
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.20
|
||||
lastReleaseVersion: 0.6.21
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.21-dev
|
||||
version: 0.6.21
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.
|
||||
@@ -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.
|
||||
14
cpp/ql/lib/change-notes/released/8.0.0.md
Normal file
14
cpp/ql/lib/change-notes/released/8.0.0.md
Normal 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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.1.1
|
||||
lastReleaseVersion: 8.0.0
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.5.12
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
cpp/ql/src/change-notes/released/1.5.12.md
Normal file
3
cpp/ql/src/change-notes/released/1.5.12.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.5.12
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.11
|
||||
lastReleaseVersion: 1.5.12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.12-dev
|
||||
version: 1.5.12
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -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(" ", "")
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
else
|
||||
Expression.Create(Context, expr!, this, 0);
|
||||
|
||||
NumberOfLines(trapFile, BodyDeclaringSymbol, this);
|
||||
NumberOfLines(trapFile, Symbol, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.60
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.59
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.60
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.59
|
||||
lastReleaseVersion: 1.7.60
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.60-dev
|
||||
version: 1.7.60
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.60
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.59
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.60
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.59
|
||||
lastReleaseVersion: 1.7.60
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.60-dev
|
||||
version: 1.7.60
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 14: Added support for the `field` keyword in properties.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 14: Added support for partial events.
|
||||
10
csharp/ql/lib/change-notes/released/5.4.8.md
Normal file
10
csharp/ql/lib/change-notes/released/5.4.8.md
Normal 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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.4.7
|
||||
lastReleaseVersion: 5.4.8
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.6.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.6.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
3
csharp/ql/src/change-notes/released/1.6.3.md
Normal file
3
csharp/ql/src/change-notes/released/1.6.3.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.6.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.6.2
|
||||
lastReleaseVersion: 1.6.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 1.6.3-dev
|
||||
version: 1.6.3
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -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 |
|
||||
12
csharp/ql/test/library-tests/dataflow/methods/MethodFlow.ql
Normal file
12
csharp/ql/test/library-tests/dataflow/methods/MethodFlow.ql
Normal 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()
|
||||
26
csharp/ql/test/library-tests/dataflow/methods/Methods.cs
Normal file
26
csharp/ql/test/library-tests/dataflow/methods/Methods.cs
Normal 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;
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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> |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | {...} |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.0.43
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.0.42
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.0.43
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.0.42
|
||||
lastReleaseVersion: 1.0.43
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql-go-consistency-queries
|
||||
version: 1.0.43-dev
|
||||
version: 1.0.43
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 7.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
3
go/ql/lib/change-notes/released/7.0.1.md
Normal file
3
go/ql/lib/change-notes/released/7.0.1.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 7.0.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.0.0
|
||||
lastReleaseVersion: 7.0.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 7.0.1-dev
|
||||
version: 7.0.1
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.5.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
go/ql/src/change-notes/released/1.5.7.md
Normal file
3
go/ql/src/change-notes/released/1.5.7.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.5.7
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.6
|
||||
lastReleaseVersion: 1.5.7
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 1.5.7-dev
|
||||
version: 1.5.7
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 8.1.0
|
||||
lastReleaseVersion: 8.1.1
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The Java extractor and QL libraries now support Java 26.
|
||||
@@ -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.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.10.7
|
||||
lastReleaseVersion: 1.10.8
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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() + "."
|
||||
@@ -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() + "."
|
||||
@@ -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 + "]."
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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() + "."
|
||||
@@ -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() + "."
|
||||
@@ -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() +
|
||||
")."
|
||||
@@ -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
Reference in New Issue
Block a user