Compare commits

..

11 Commits

Author SHA1 Message Date
yoff
73ab3e6888 Update shared/controlflow/codeql/controlflow/ControlFlowGraph.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2026-06-23 12:41:02 +02:00
yoff
15cbbb82eb Shared CFG: add defaulted getLoopElse to AstSig
Adds a new defaulted signature predicates to the shared CFG library:

- getLoopElse: `else` block of a loop statement, if
  any (used by Python's `while-else` / `for-else` constructs).

The predicate defaults to `none()`, so behaviour is unchanged for any
language that doesn't override it (verified by re-running
java/ql/test/library-tests/controlflow/).

The Make0 succession rules are extended:
- WhileStmt/ForeachStmt: route the loop-exit edge through the else
  block before reaching the after-position.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 12:41:02 +02:00
Geoffrey White
f6dce466a0 Merge pull request #22009 from geoffw0/rust-crypto
Rust: Additional test cases for rust/weak-sensitive-data-hashing
2026-06-23 10:53:45 +01:00
Idriss Riouak
ec91865a7f Merge pull request #22030 from github/idrissrio/cpp/update-stats-file
C/C++: Update stats file
2026-06-23 10:26:52 +02:00
Geoffrey White
9e0e1bde28 Rust: Use Copilot suggested comment phrasing. 2026-06-22 16:12:54 +01:00
Geoffrey White
8c24acc99d Fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 16:10:57 +01:00
idrissrio
0a41157d77 C/C++: update stats file 2026-06-22 10:27:21 +02:00
Geoffrey White
721070a191 Rust: Make the Seed case a tiny bit more realistic. 2026-06-18 23:43:18 +01:00
Geoffrey White
b86cb6df63 Rust: Additional test cases for weak sensitive data hashing. 2026-06-18 23:32:38 +01:00
Geoffrey White
3aaeb68553 Rust: Make the new test inline expectations. 2026-06-18 22:57:15 +01:00
Geoffrey White
e8923b7688 Rust: Output cryptographic operations in the weak sensitive data hashing query test. 2026-06-18 17:07:28 +01:00
25 changed files with 4036 additions and 4017 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
{
var type = Type.Create(Context, Context.GetType(Stmt.Declaration!.Type));
trapFile.catch_type(this, type.TypeRef, true);
Expression.Create(Context, Stmt.Declaration!.Type, this, 0);
TypeMention.Create(Context, Stmt.Declaration!.Type, this, type);
}
else // A catch clause of the form 'catch { ... }'
{

View File

@@ -995,23 +995,6 @@ class SpecificCatchClause extends CatchClause {
/** Gets the local variable declaration of this catch clause, if any. */
LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this }
/**
* Gets the type access of this catch clause, if it has no variable declaration.
*
* For example, the type access in
*
* ```csharp
* try { ... }
* catch (IOException) { ... }
* ```
*
* is `IOException`.
*/
TypeAccess getTypeAccess() {
not exists(this.getVariableDeclExpr()) and
result = this.getChild(0)
}
override string toString() { result = "catch (...) {...}" }
override string getAPrimaryQlClass() { result = "SpecificCatchClause" }

View File

@@ -90,7 +90,6 @@ module Ast implements AstSig<Location> {
private AstNode getStmtChild0(Stmt s, int i) {
not s instanceof FixedStmt and
not s instanceof UsingBlockStmt and
not skipControlFlow(result) and
result = s.getChild(i)
or
s =

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The C# extractor now extracts the exception type in a `catch(ExceptionType)` clause (without a variable) as a `TypeAccess` expression instead of a `TypeMention`. The new `SpecificCatchClause.getTypeAccess()` predicate provides access to this expression.

View File

@@ -101,8 +101,7 @@ csharp6.cs:
# 32| 0: [IntLiteral] 2
# 32| 0: [IntLiteral] 1
# 34| 1: [SpecificCatchClause] catch (...) {...}
# 34| 0: [TypeAccess] access to type IndexOutOfRangeException
# 34| 0: [TypeMention] IndexOutOfRangeException
# 34| 0: [TypeMention] IndexOutOfRangeException
# 35| 1: [BlockStmt] {...}
# 34| 2: [EQExpr] ... == ...
# 34| 0: [PropertyCall] access to property Value

View File

@@ -1 +1 @@
| statements.cs:250:13:253:13 | checked {...} | statements.cs:251:13:253:13 | {...} |
| statements.cs:234:13:237:13 | checked {...} | statements.cs:235:13:237:13 | {...} |

View File

@@ -1,3 +1,3 @@
| fixed.cs:3:7:3:11 | {...} | fixed.cs:3:7:3:11 | Fixed |
| statements.cs:8:11:8:15 | {...} | statements.cs:8:11:8:15 | Class |
| statements.cs:260:15:260:25 | {...} | statements.cs:260:15:260:25 | AccountLock |
| statements.cs:244:15:244:25 | {...} | statements.cs:244:15:244:25 | AccountLock |

View File

@@ -1 +1 @@
| statements.cs:289:21:289:31 | MainLabeled | statements.cs:292:9:292:13 | Label: |
| statements.cs:273:21:273:31 | MainLabeled | statements.cs:276:9:276:13 | Label: |

View File

@@ -1 +1 @@
| statements.cs:265:17:272:17 | lock (...) {...} | statements.cs:265:23:265:26 | this access | statements.cs:266:17:272:17 | {...} |
| statements.cs:249:17:256:17 | lock (...) {...} | statements.cs:249:23:249:26 | this access | statements.cs:250:17:256:17 | {...} |

View File

@@ -1 +1 @@
| statements.cs:301:13:304:13 | lock (...) {...} | statements.cs:301:19:301:28 | access to field lockObject | Lock | statements.cs:302:13:304:13 | {...} |
| statements.cs:285:13:288:13 | lock (...) {...} | statements.cs:285:19:285:28 | access to field lockObject | Lock | statements.cs:286:13:288:13 | {...} |

View File

@@ -603,147 +603,115 @@ statements.cs:
# 223| -1: [TypeAccess] access to type Console
# 223| 0: [TypeMention] Console
# 223| 0: [StringLiteralUtf16] "Exception"
# 231| 27: [Method] MainTryCatchNoVar
# 231| 27: [Method] MainCheckedUnchecked
# 231| -1: [TypeMention] Void
#-----| 2: (Parameters)
# 231| 0: [Parameter] args
# 231| -1: [TypeMention] String[]
# 231| 1: [TypeMention] string
# 232| 4: [BlockStmt] {...}
# 233| 0: [TryStmt] try {...} ...
# 234| 0: [BlockStmt] {...}
# 235| 0: [ExprStmt] ...;
# 235| 0: [MethodCall] call to method WriteLine
# 235| -1: [TypeAccess] access to type Console
# 235| 0: [TypeMention] Console
# 235| 0: [StringLiteralUtf16] "try"
# 237| 1: [SpecificCatchClause] catch (...) {...}
# 237| 0: [TypeAccess] access to type IOException
# 237| 0: [TypeMention] IOException
# 238| 1: [BlockStmt] {...}
# 239| 0: [ExprStmt] ...;
# 239| 0: [MethodCall] call to method WriteLine
# 239| -1: [TypeAccess] access to type Console
# 239| 0: [TypeMention] Console
# 239| 0: [StringLiteralUtf16] "catch (IOException) without variable"
# 241| 2: [SpecificCatchClause] catch (...) {...}
# 241| 0: [TypeAccess] access to type Exception
# 241| 0: [TypeMention] Exception
# 242| 1: [BlockStmt] {...}
# 243| 0: [ExprStmt] ...;
# 243| 0: [MethodCall] call to method WriteLine
# 243| -1: [TypeAccess] access to type Console
# 243| 0: [TypeMention] Console
# 243| 0: [StringLiteralUtf16] "catch (Exception) without variable"
# 247| 28: [Method] MainCheckedUnchecked
# 247| -1: [TypeMention] Void
# 248| 4: [BlockStmt] {...}
# 249| 0: [LocalVariableDeclStmt] ... ...;
# 249| 0: [LocalVariableDeclAndInitExpr] Int32 i = ...
# 249| -1: [TypeMention] int
# 249| 0: [LocalVariableAccess] access to local variable i
# 249| 1: [MemberConstantAccess] access to constant MaxValue
# 249| -1: [TypeAccess] access to type Int32
# 249| 0: [TypeMention] int
# 250| 1: [CheckedStmt] checked {...}
# 251| 0: [BlockStmt] {...}
# 252| 0: [ExprStmt] ...;
# 252| 0: [MethodCall] call to method WriteLine
# 252| -1: [TypeAccess] access to type Console
# 252| 0: [TypeMention] Console
# 252| 0: [AddExpr] ... + ...
# 252| 0: [LocalVariableAccess] access to local variable i
# 252| 1: [IntLiteral] 1
# 254| 2: [UncheckedStmt] unchecked {...}
# 255| 0: [BlockStmt] {...}
# 256| 0: [ExprStmt] ...;
# 256| 0: [MethodCall] call to method WriteLine
# 256| -1: [TypeAccess] access to type Console
# 256| 0: [TypeMention] Console
# 256| 0: [AddExpr] ... + ...
# 256| 0: [LocalVariableAccess] access to local variable i
# 256| 1: [IntLiteral] 1
# 260| 29: [Class] AccountLock
# 262| 6: [Field] balance
# 262| -1: [TypeMention] decimal
# 263| 7: [Method] Withdraw
# 263| -1: [TypeMention] Void
# 233| 0: [LocalVariableDeclStmt] ... ...;
# 233| 0: [LocalVariableDeclAndInitExpr] Int32 i = ...
# 233| -1: [TypeMention] int
# 233| 0: [LocalVariableAccess] access to local variable i
# 233| 1: [MemberConstantAccess] access to constant MaxValue
# 233| -1: [TypeAccess] access to type Int32
# 233| 0: [TypeMention] int
# 234| 1: [CheckedStmt] checked {...}
# 235| 0: [BlockStmt] {...}
# 236| 0: [ExprStmt] ...;
# 236| 0: [MethodCall] call to method WriteLine
# 236| -1: [TypeAccess] access to type Console
# 236| 0: [TypeMention] Console
# 236| 0: [AddExpr] ... + ...
# 236| 0: [LocalVariableAccess] access to local variable i
# 236| 1: [IntLiteral] 1
# 238| 2: [UncheckedStmt] unchecked {...}
# 239| 0: [BlockStmt] {...}
# 240| 0: [ExprStmt] ...;
# 240| 0: [MethodCall] call to method WriteLine
# 240| -1: [TypeAccess] access to type Console
# 240| 0: [TypeMention] Console
# 240| 0: [AddExpr] ... + ...
# 240| 0: [LocalVariableAccess] access to local variable i
# 240| 1: [IntLiteral] 1
# 244| 28: [Class] AccountLock
# 246| 6: [Field] balance
# 246| -1: [TypeMention] decimal
# 247| 7: [Method] Withdraw
# 247| -1: [TypeMention] Void
#-----| 2: (Parameters)
# 263| 0: [Parameter] amount
# 263| -1: [TypeMention] decimal
# 264| 4: [BlockStmt] {...}
# 265| 0: [LockStmt] lock (...) {...}
# 265| 0: [ThisAccess] this access
# 266| 1: [BlockStmt] {...}
# 267| 0: [IfStmt] if (...) ...
# 267| 0: [GTExpr] ... > ...
# 267| 0: [ParameterAccess] access to parameter amount
# 267| 1: [FieldAccess] access to field balance
# 268| 1: [BlockStmt] {...}
# 269| 0: [ThrowStmt] throw ...;
# 269| 0: [ObjectCreation] object creation of type Exception
# 269| -1: [TypeMention] Exception
# 269| 0: [StringLiteralUtf16] "Insufficient funds"
# 271| 1: [ExprStmt] ...;
# 271| 0: [AssignSubExpr] ... -= ...
# 271| 0: [FieldAccess] access to field balance
# 271| 1: [ParameterAccess] access to parameter amount
# 276| 30: [Method] MainUsing
# 276| -1: [TypeMention] Void
# 277| 4: [BlockStmt] {...}
# 278| 0: [UsingBlockStmt] using (...) {...}
# 278| -1: [LocalVariableDeclAndInitExpr] TextWriter w = ...
# 278| -1: [TypeMention] TextWriter
# 278| 0: [LocalVariableAccess] access to local variable w
# 278| 1: [MethodCall] call to method CreateText
# 278| -1: [TypeAccess] access to type File
# 278| 0: [TypeMention] File
# 278| 0: [StringLiteralUtf16] "test.txt"
# 279| 1: [BlockStmt] {...}
# 280| 0: [ExprStmt] ...;
# 280| 0: [MethodCall] call to method WriteLine
# 280| -1: [LocalVariableAccess] access to local variable w
# 280| 0: [StringLiteralUtf16] "Line one"
# 281| 1: [ExprStmt] ...;
# 281| 0: [MethodCall] call to method WriteLine
# 281| -1: [LocalVariableAccess] access to local variable w
# 281| 0: [StringLiteralUtf16] "Line two"
# 282| 2: [ExprStmt] ...;
# 282| 0: [MethodCall] call to method WriteLine
# 282| -1: [LocalVariableAccess] access to local variable w
# 282| 0: [StringLiteralUtf16] "Line three"
# 284| 1: [UsingBlockStmt] using (...) {...}
# 284| 0: [MethodCall] call to method CreateText
# 284| -1: [TypeAccess] access to type File
# 284| 0: [TypeMention] File
# 284| 0: [StringLiteralUtf16] "test.txt"
# 285| 1: [BlockStmt] {...}
# 289| 31: [Method] MainLabeled
# 289| -1: [TypeMention] Void
# 290| 4: [BlockStmt] {...}
# 291| 0: [GotoLabelStmt] goto ...;
# 292| 1: [LabelStmt] Label:
# 293| 2: [LocalVariableDeclStmt] ... ...;
# 293| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
# 293| -1: [TypeMention] int
# 293| 0: [LocalVariableAccess] access to local variable x
# 293| 1: [IntLiteral] 23
# 294| 3: [ExprStmt] ...;
# 294| 0: [AssignExpr] ... = ...
# 294| 0: [LocalVariableAccess] access to local variable x
# 294| 1: [IntLiteral] 9
# 297| 32: [Field] lockObject
# 297| -1: [TypeMention] Lock
# 297| 1: [ObjectCreation] object creation of type Lock
# 297| 0: [TypeMention] Lock
# 299| 33: [Method] LockMethod
# 299| -1: [TypeMention] Void
# 300| 4: [BlockStmt] {...}
# 301| 0: [LockStmt] lock (...) {...}
# 301| 0: [FieldAccess] access to field lockObject
# 302| 1: [BlockStmt] {...}
# 303| 0: [ExprStmt] ...;
# 303| 0: [MethodCall] call to method WriteLine
# 303| -1: [TypeAccess] access to type Console
# 303| 0: [TypeMention] Console
# 303| 0: [StringLiteralUtf16] "Locked"
# 247| 0: [Parameter] amount
# 247| -1: [TypeMention] decimal
# 248| 4: [BlockStmt] {...}
# 249| 0: [LockStmt] lock (...) {...}
# 249| 0: [ThisAccess] this access
# 250| 1: [BlockStmt] {...}
# 251| 0: [IfStmt] if (...) ...
# 251| 0: [GTExpr] ... > ...
# 251| 0: [ParameterAccess] access to parameter amount
# 251| 1: [FieldAccess] access to field balance
# 252| 1: [BlockStmt] {...}
# 253| 0: [ThrowStmt] throw ...;
# 253| 0: [ObjectCreation] object creation of type Exception
# 253| -1: [TypeMention] Exception
# 253| 0: [StringLiteralUtf16] "Insufficient funds"
# 255| 1: [ExprStmt] ...;
# 255| 0: [AssignSubExpr] ... -= ...
# 255| 0: [FieldAccess] access to field balance
# 255| 1: [ParameterAccess] access to parameter amount
# 260| 29: [Method] MainUsing
# 260| -1: [TypeMention] Void
# 261| 4: [BlockStmt] {...}
# 262| 0: [UsingBlockStmt] using (...) {...}
# 262| -1: [LocalVariableDeclAndInitExpr] TextWriter w = ...
# 262| -1: [TypeMention] TextWriter
# 262| 0: [LocalVariableAccess] access to local variable w
# 262| 1: [MethodCall] call to method CreateText
# 262| -1: [TypeAccess] access to type File
# 262| 0: [TypeMention] File
# 262| 0: [StringLiteralUtf16] "test.txt"
# 263| 1: [BlockStmt] {...}
# 264| 0: [ExprStmt] ...;
# 264| 0: [MethodCall] call to method WriteLine
# 264| -1: [LocalVariableAccess] access to local variable w
# 264| 0: [StringLiteralUtf16] "Line one"
# 265| 1: [ExprStmt] ...;
# 265| 0: [MethodCall] call to method WriteLine
# 265| -1: [LocalVariableAccess] access to local variable w
# 265| 0: [StringLiteralUtf16] "Line two"
# 266| 2: [ExprStmt] ...;
# 266| 0: [MethodCall] call to method WriteLine
# 266| -1: [LocalVariableAccess] access to local variable w
# 266| 0: [StringLiteralUtf16] "Line three"
# 268| 1: [UsingBlockStmt] using (...) {...}
# 268| 0: [MethodCall] call to method CreateText
# 268| -1: [TypeAccess] access to type File
# 268| 0: [TypeMention] File
# 268| 0: [StringLiteralUtf16] "test.txt"
# 269| 1: [BlockStmt] {...}
# 273| 30: [Method] MainLabeled
# 273| -1: [TypeMention] Void
# 274| 4: [BlockStmt] {...}
# 275| 0: [GotoLabelStmt] goto ...;
# 276| 1: [LabelStmt] Label:
# 277| 2: [LocalVariableDeclStmt] ... ...;
# 277| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
# 277| -1: [TypeMention] int
# 277| 0: [LocalVariableAccess] access to local variable x
# 277| 1: [IntLiteral] 23
# 278| 3: [ExprStmt] ...;
# 278| 0: [AssignExpr] ... = ...
# 278| 0: [LocalVariableAccess] access to local variable x
# 278| 1: [IntLiteral] 9
# 281| 31: [Field] lockObject
# 281| -1: [TypeMention] Lock
# 281| 1: [ObjectCreation] object creation of type Lock
# 281| 0: [TypeMention] Lock
# 283| 32: [Method] LockMethod
# 283| -1: [TypeMention] Void
# 284| 4: [BlockStmt] {...}
# 285| 0: [LockStmt] lock (...) {...}
# 285| 0: [FieldAccess] access to field lockObject
# 286| 1: [BlockStmt] {...}
# 287| 0: [ExprStmt] ...;
# 287| 0: [MethodCall] call to method WriteLine
# 287| -1: [TypeAccess] access to type Console
# 287| 0: [TypeMention] Console
# 287| 0: [StringLiteralUtf16] "Locked"

View File

@@ -17,13 +17,9 @@
| statements.cs:218:13:220:13 | {...} | statements.cs:219:17:219:45 | ...; |
| statements.cs:222:13:224:13 | {...} | statements.cs:223:17:223:47 | ...; |
| statements.cs:226:13:228:13 | {...} | statements.cs:227:17:227:47 | ...; |
| statements.cs:232:9:245:9 | {...} | statements.cs:233:13:244:13 | try {...} ... |
| statements.cs:234:13:236:13 | {...} | statements.cs:235:17:235:41 | ...; |
| statements.cs:238:13:240:13 | {...} | statements.cs:239:17:239:74 | ...; |
| statements.cs:242:13:244:13 | {...} | statements.cs:243:17:243:72 | ...; |
| statements.cs:251:13:253:13 | {...} | statements.cs:252:17:252:41 | ...; |
| statements.cs:255:13:257:13 | {...} | statements.cs:256:17:256:41 | ...; |
| statements.cs:264:13:273:13 | {...} | statements.cs:265:17:272:17 | lock (...) {...} |
| statements.cs:268:21:270:21 | {...} | statements.cs:269:25:269:66 | throw ...; |
| statements.cs:300:9:305:9 | {...} | statements.cs:301:13:304:13 | lock (...) {...} |
| statements.cs:302:13:304:13 | {...} | statements.cs:303:17:303:44 | ...; |
| statements.cs:235:13:237:13 | {...} | statements.cs:236:17:236:41 | ...; |
| statements.cs:239:13:241:13 | {...} | statements.cs:240:17:240:41 | ...; |
| statements.cs:248:13:257:13 | {...} | statements.cs:249:17:256:17 | lock (...) {...} |
| statements.cs:252:21:254:21 | {...} | statements.cs:253:25:253:66 | throw ...; |
| statements.cs:284:9:289:9 | {...} | statements.cs:285:13:288:13 | lock (...) {...} |
| statements.cs:286:13:288:13 | {...} | statements.cs:287:17:287:44 | ...; |

View File

@@ -1,2 +1,2 @@
| statements.cs:262:21:262:27 | balance |
| statements.cs:297:31:297:40 | lockObject |
| statements.cs:246:21:246:27 | balance |
| statements.cs:281:31:281:40 | lockObject |

View File

@@ -1,2 +0,0 @@
| statements.cs:237:13:240:13 | catch (...) {...} | statements.cs:237:20:237:30 | access to type IOException | file:///home/runner/work/codeql/codeql/csharp/extractor-pack/tools/linux64/System.Private.CoreLib.dll:0:0:0:0 | IOException |
| statements.cs:241:13:244:13 | catch (...) {...} | statements.cs:241:20:241:28 | access to type Exception | file:///home/runner/work/codeql/codeql/csharp/extractor-pack/tools/linux64/System.Private.CoreLib.dll:0:0:0:0 | Exception |

View File

@@ -1,13 +0,0 @@
/**
* @name Test for try catches without variable
*/
import csharp
from Method m, TryStmt s, SpecificCatchClause c, TypeAccess ta
where
s.getEnclosingCallable() = m and
m.getName() = "MainTryCatchNoVar" and
s.getACatchClause() = c and
c.getTypeAccess() = ta
select c, ta, ta.getTarget()

View File

@@ -1 +1 @@
| statements.cs:254:13:257:13 | unchecked {...} | statements.cs:255:13:257:13 | {...} |
| statements.cs:238:13:241:13 | unchecked {...} | statements.cs:239:13:241:13 | {...} |

View File

@@ -1 +1 @@
| statements.cs:276:21:276:29 | MainUsing |
| statements.cs:260:21:260:29 | MainUsing |

View File

@@ -1 +1 @@
| statements.cs:276:21:276:29 | MainUsing | statements.cs:278:31:278:31 | w |
| statements.cs:260:21:260:29 | MainUsing | statements.cs:262:31:262:31 | w |

View File

@@ -228,22 +228,6 @@ namespace Statements
}
}
static void MainTryCatchNoVar(string[] args)
{
try
{
Console.WriteLine("try");
}
catch (IOException)
{
Console.WriteLine("catch (IOException) without variable");
}
catch (Exception)
{
Console.WriteLine("catch (Exception) without variable");
}
}
static void MainCheckedUnchecked()
{
int i = int.MaxValue;

View File

@@ -0,0 +1,12 @@
| test.rs:19:9:19:34 | ...::compute(...) | HashingAlgorithm MD5 WEAK inputs:1 |
| test.rs:20:9:20:40 | ...::compute(...) | HashingAlgorithm MD5 WEAK inputs:1 |
| test.rs:21:9:21:34 | ...::compute(...) | HashingAlgorithm MD5 WEAK inputs:1 |
| test.rs:22:9:22:44 | ...::compute(...) | HashingAlgorithm MD5 WEAK inputs:1 |
| test.rs:67:26:67:40 | ...::new(...) | HashingAlgorithm MD5 WEAK |
| test.rs:73:9:73:23 | ...::new(...) | HashingAlgorithm MD5 WEAK |
| test.rs:74:9:74:23 | ...::new(...) | HashingAlgorithm MD5 WEAK |
| test.rs:133:26:133:40 | ...::new(...) | HashingAlgorithm MD5 WEAK |
| test.rs:156:26:156:40 | ...::new(...) | HashingAlgorithm MD5 WEAK |
| test.rs:176:13:176:24 | ...::new(...) | EncryptionAlgorithm SEED |
| test.rs:199:22:199:32 | ...::new(...) | HashingAlgorithm SHA1 WEAK |
| test.rs:211:13:211:35 | ...::compute(...) | HashingAlgorithm MD5 WEAK inputs:1 |

View File

@@ -0,0 +1,3 @@
query: queries/summary/CryptographicOperations.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,9 +1,13 @@
#select
| test.rs:20:9:20:24 | ...::compute | test.rs:20:26:20:39 | credit_card_no | test.rs:20:9:20:24 | ...::compute | $@ is used in a hashing algorithm (MD5) that is insecure. | test.rs:20:26:20:39 | credit_card_no | Sensitive data (private) |
| test.rs:21:9:21:24 | ...::compute | test.rs:21:26:21:33 | password | test.rs:21:9:21:24 | ...::compute | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test.rs:21:26:21:33 | password | Sensitive data (password) |
| test.rs:211:13:211:28 | ...::compute | test.rs:226:29:226:36 | password | test.rs:211:13:211:28 | ...::compute | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test.rs:226:29:226:36 | password | Sensitive data (password) |
edges
| test.rs:20:26:20:39 | credit_card_no | test.rs:20:9:20:24 | ...::compute | provenance | MaD:1 Sink:MaD:1 |
| test.rs:21:26:21:33 | password | test.rs:21:9:21:24 | ...::compute | provenance | MaD:1 Sink:MaD:1 |
| test.rs:210:20:210:30 | ...: ... | test.rs:211:30:211:34 | value | provenance | |
| test.rs:211:30:211:34 | value | test.rs:211:13:211:28 | ...::compute | provenance | MaD:1 Sink:MaD:1 |
| test.rs:226:29:226:36 | password | test.rs:210:20:210:30 | ...: ... | provenance | |
models
| 1 | Sink: md5::compute; Argument[0]; hasher-input |
nodes
@@ -11,4 +15,8 @@ nodes
| test.rs:20:26:20:39 | credit_card_no | semmle.label | credit_card_no |
| test.rs:21:9:21:24 | ...::compute | semmle.label | ...::compute |
| test.rs:21:26:21:33 | password | semmle.label | password |
| test.rs:210:20:210:30 | ...: ... | semmle.label | ...: ... |
| test.rs:211:13:211:28 | ...::compute | semmle.label | ...::compute |
| test.rs:211:30:211:34 | value | semmle.label | value |
| test.rs:226:29:226:36 | password | semmle.label | password |
subpaths

View File

@@ -16,10 +16,10 @@ fn test_hash_algorithms(
_ = md5::Md5::digest(encrypted_password);
// MD5 (alternative / older library)
_ = md5_alt::compute(harmless);
_ = md5_alt::compute(credit_card_no); // $ Alert[rust/weak-sensitive-data-hashing]
_ = md5_alt::compute(password); // $ Alert[rust/weak-sensitive-data-hashing]
_ = md5_alt::compute(encrypted_password);
_ = md5_alt::compute(harmless); // $ Alert[rust/summary/cryptographic-operations]
_ = md5_alt::compute(credit_card_no); // $ Alert[rust/summary/cryptographic-operations] Alert[rust/weak-sensitive-data-hashing]
_ = md5_alt::compute(password); // $ Alert[rust/summary/cryptographic-operations] Alert[rust/weak-sensitive-data-hashing]
_ = md5_alt::compute(encrypted_password); // $ Alert[rust/summary/cryptographic-operations]
// SHA-1
_ = sha1::Sha1::digest(harmless);
@@ -64,14 +64,14 @@ fn test_hash_code_patterns(
_ = md5::Md5::digest(password_vec); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
// hash through a hasher object
let mut md5_hasher = md5::Md5::new();
let mut md5_hasher = md5::Md5::new(); // $ Alert[rust/summary/cryptographic-operations]
md5_hasher.update(b"abc");
md5_hasher.update(harmless);
md5_hasher.update(password); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
_ = md5_hasher.finalize();
_ = md5::Md5::new().chain_update(harmless).chain_update(harmless).chain_update(harmless).finalize();
_ = md5::Md5::new().chain_update(harmless).chain_update(password).chain_update(harmless).finalize(); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
_ = md5::Md5::new().chain_update(harmless).chain_update(harmless).chain_update(harmless).finalize(); // $ Alert[rust/summary/cryptographic-operations]
_ = md5::Md5::new().chain_update(harmless).chain_update(password).chain_update(harmless).finalize(); // $ Alert[rust/summary/cryptographic-operations] MISSING: Alert[rust/weak-sensitive-data-hashing]
_ = md5::Md5::new_with_prefix(harmless).finalize();
_ = md5::Md5::new_with_prefix(password).finalize(); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
@@ -130,7 +130,7 @@ fn test_hash_structs() {
let str3c = serde_urlencoded::to_string(&s3).unwrap();
// hash with MD5
let mut md5_hasher = md5::Md5::new();
let mut md5_hasher = md5::Md5::new(); // $ Alert[rust/summary/cryptographic-operations]
md5_hasher.update(s1.data);
md5_hasher.update(s2.credit_card_no); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
md5_hasher.update(s3.password); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
@@ -153,8 +153,75 @@ fn test_hash_file(
let mut harmless_file = std::fs::File::open(harmless_filename).unwrap();
let mut password_file = std::fs::File::open(password_filename).unwrap();
let mut md5_hasher = md5::Md5::new();
let mut md5_hasher = md5::Md5::new(); // $ Alert[rust/summary/cryptographic-operations]
_ = std::io::copy(&mut harmless_file, &mut md5_hasher);
_ = std::io::copy(&mut password_file, &mut md5_hasher); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
_ = md5_hasher.finalize();
}
// ---
struct Seed {
}
impl Seed {
fn new(_seed_value: u64) -> Self {
Seed { }
}
}
fn test_seed() {
// this will be misrecognized as a use of the SEED algorithm, but SEED is strong and the input
// is not sensitive data, so `rust/weak-sensitive-data-hashing` should not report a result here.
let _ = Seed::new(0); // $ Alert[rust/summary/cryptographic-operations]
}
// ---
struct Sha1 {
}
impl Sha1 {
const fn new() -> Self {
Sha1 { }
}
const fn update(&mut self, _data: &[u8]) {
// ...
}
const fn finalize(self) -> [u8; 20] {
[0; 20]
}
}
fn sha1_test(password: &[u8]) {
let mut hasher = Sha1::new(); // $ Alert[rust/summary/cryptographic-operations]
hasher.update(password); // $ MISSING: Alert[rust/weak-sensitive-data-hashing]
_ = hasher.finalize();
}
// ---
struct HashCollection {
}
impl HashCollection {
pub fn add_sig(value: &str) -> Self {
_ = md5_alt::compute(value); // $ Alert[rust/summary/cryptographic-operations] Alert[rust/weak-sensitive-data-hashing]
// ...
HashCollection { }
}
}
fn test_hash_collection() {
// this indirectly performs MD5 hashing, but the data is not sensitive
let id: &str = "my_id_1234567890";
HashCollection::add_sig(id);
// this indirectly performs MD5 hashing, and the data is sensitive; the result is reported here
let password: &str = "password123";
HashCollection::add_sig(password); // $ Source
}

View File

@@ -224,6 +224,13 @@ signature module AstSig<LocationSig Location> {
*/
default AstNode getTryElse(TryStmt try) { none() }
/**
* Gets the `else` block of loop statement `loop`, if any.
*
* Only some languages (e.g. Python) support `for-else` constructs.
*/
default AstNode getLoopElse(LoopStmt loop) { none() }
/** A catch clause in a try statement. */
class CatchClause extends AstNode {
/** Gets the variable declared by this catch clause. */
@@ -1578,19 +1585,32 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
n2.isBefore(loopstmt.getBody())
or
n1.isAfterValue(cond, any(BooleanSuccessor b | b.getValue() = while.booleanNot())) and
n2.isAfter(loopstmt)
(
n2.isBefore(getLoopElse(loopstmt))
or
not exists(getLoopElse(loopstmt)) and n2.isAfter(loopstmt)
)
or
n1.isAfter(loopstmt.getBody()) and
n2.isAdditional(loopstmt, loopHeaderTag())
)
or
exists(LoopStmt loopstmt |
n1.isAfter(getLoopElse(loopstmt)) and
n2.isAfter(loopstmt)
)
or
exists(ForeachStmt foreachstmt |
n1.isBefore(foreachstmt) and
n2.isBefore(foreachstmt.getCollection())
or
n1.isAfterValue(foreachstmt.getCollection(),
any(EmptinessSuccessor t | t.getValue() = true)) and
n2.isAfter(foreachstmt)
(
n2.isBefore(getLoopElse(foreachstmt))
or
not exists(getLoopElse(foreachstmt)) and n2.isAfter(foreachstmt)
)
or
n1.isAfterValue(foreachstmt.getCollection(),
any(EmptinessSuccessor t | t.getValue() = false)) and
@@ -1603,7 +1623,11 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
n2.isAdditional(foreachstmt, loopHeaderTag())
or
n1.isAdditional(foreachstmt, loopHeaderTag()) and
n2.isAfter(foreachstmt)
(
n2.isBefore(getLoopElse(foreachstmt))
or
not exists(getLoopElse(foreachstmt)) and n2.isAfter(foreachstmt)
)
or
n1.isAdditional(foreachstmt, loopHeaderTag()) and
n2.isBefore(foreachstmt.getVariable())