Compare commits

..

1 Commits

Author SHA1 Message Date
Arthur Baars
c3ae3a5770 Update 2025-08-25-loc-option.md 2025-09-01 22:39:13 +02:00
3135 changed files with 62244 additions and 176937 deletions

4
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,4 @@
When reviewing code:
* do not review changes in files with `.expected` extension (they are automatically ensured to be correct).
* in `.ql` and `.qll` files, do not try to review the code itself as you don't understand the programming language
well enough to make comments in these languages. You can still check for typos or comment improvements.

View File

@@ -1,4 +0,0 @@
---
applyTo: "**/*.expected"
---
Ignore these files. These are generated to be correct by running the tests, and should not be edited manually.

View File

@@ -1,6 +0,0 @@
---
applyTo: "**/*.ql,**/*.qll"
---
When reviewing these QL files, do not make any comment on the code itself. You don't understand the QL programming language well enough yet. You can only make comments about the following aspects:
* comments (lines starting with `//` or block comments enclosed in `/* ... */`): you can suggest improvements to the clarity of comments, or point out spelling mistakes
* typos in identifiers

View File

@@ -34,7 +34,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.300
dotnet-version: 9.0.100
- name: Checkout repository
uses: actions/checkout@v5

View File

@@ -43,14 +43,14 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.300
dotnet-version: 9.0.100
- name: Extractor unit tests
run: |
dotnet tool restore
dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Util.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Extraction.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.CSharp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.Cpp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Util.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Extraction.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.CSharp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.Cpp.Tests
shell: bash
stubgentest:
runs-on: ubuntu-latest

View File

@@ -31,7 +31,7 @@ jobs:
with:
python-version: 3.8
- name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql
- name: Build code scanning query list
run: |

3
.gitignore vendored
View File

@@ -76,6 +76,3 @@ node_modules/
# some upgrade/downgrade checks create these files
**/upgrades/*/*.dbscheme.stats
**/downgrades/*/*.dbscheme.stats
# Mergetool files
*.orig

View File

@@ -1,7 +1,3 @@
# Catch-all for anything which isn't matched by a line lower down
* @github/code-scanning-alert-coverage
# CodeQL language libraries
/actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp
@@ -11,10 +7,8 @@
/java/ @github/codeql-java
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ql/ @github/codeql-ql-for-ql-reviewers
/ruby/ @github/codeql-ruby
/rust/ @github/codeql-rust
/shared/ @github/codeql-shared-libraries-reviewers
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin
@@ -31,6 +25,9 @@
/docs/codeql/ql-language-reference/ @github/codeql-frontend-reviewers
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
# QL for QL reviewers
/ql/ @github/codeql-ql-for-ql-reviewers
# Bazel (excluding BUILD.bazel files)
MODULE.bazel @github/codeql-ci-reviewers
.bazelversion @github/codeql-ci-reviewers

763
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,3 +10,4 @@ members = [
"rust/ast-generator",
"rust/autobuild",
]
exclude = ["mad-generation-build"]

View File

@@ -19,16 +19,16 @@ bazel_dep(name = "rules_go", version = "0.56.1")
bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.40.0")
bazel_dep(name = "rules_shell", version = "0.5.0")
bazel_dep(name = "bazel_skylib", version = "1.8.1")
bazel_dep(name = "rules_shell", version = "0.3.0")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "10.0.0")
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.19.2-codeql.1")
bazel_dep(name = "rules_dotnet", version = "0.17.4")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
bazel_dep(name = "rules_rust", version = "0.66.0")
bazel_dep(name = "rules_rust", version = "0.63.0")
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
@@ -89,8 +89,8 @@ use_repo(
"vendor_py__cc-1.2.14",
"vendor_py__clap-4.5.30",
"vendor_py__regex-1.11.1",
"vendor_py__tree-sitter-0.24.7",
"vendor_py__tree-sitter-graph-0.12.0",
"vendor_py__tree-sitter-0.20.4",
"vendor_py__tree-sitter-graph-0.7.0",
)
# deps for ruby+rust
@@ -98,54 +98,54 @@ use_repo(
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(
tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.100",
"vendor_ts__anyhow-1.0.99",
"vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.104.0",
"vendor_ts__chrono-0.4.42",
"vendor_ts__clap-4.5.48",
"vendor_ts__chrono-0.4.41",
"vendor_ts__clap-4.5.44",
"vendor_ts__dunce-1.0.5",
"vendor_ts__either-1.15.0",
"vendor_ts__encoding-0.2.33",
"vendor_ts__figment-0.10.19",
"vendor_ts__flate2-1.1.2",
"vendor_ts__flate2-1.1.0",
"vendor_ts__glob-0.3.3",
"vendor_ts__globset-0.4.16",
"vendor_ts__globset-0.4.15",
"vendor_ts__itertools-0.14.0",
"vendor_ts__lazy_static-1.5.0",
"vendor_ts__mustache-0.9.0",
"vendor_ts__num-traits-0.2.19",
"vendor_ts__num_cpus-1.17.0",
"vendor_ts__proc-macro2-1.0.101",
"vendor_ts__quote-1.0.41",
"vendor_ts__ra_ap_base_db-0.0.301",
"vendor_ts__ra_ap_cfg-0.0.301",
"vendor_ts__ra_ap_hir-0.0.301",
"vendor_ts__ra_ap_hir_def-0.0.301",
"vendor_ts__ra_ap_hir_expand-0.0.301",
"vendor_ts__ra_ap_hir_ty-0.0.301",
"vendor_ts__ra_ap_ide_db-0.0.301",
"vendor_ts__ra_ap_intern-0.0.301",
"vendor_ts__ra_ap_load-cargo-0.0.301",
"vendor_ts__ra_ap_parser-0.0.301",
"vendor_ts__ra_ap_paths-0.0.301",
"vendor_ts__ra_ap_project_model-0.0.301",
"vendor_ts__ra_ap_span-0.0.301",
"vendor_ts__ra_ap_stdx-0.0.301",
"vendor_ts__ra_ap_syntax-0.0.301",
"vendor_ts__ra_ap_vfs-0.0.301",
"vendor_ts__proc-macro2-1.0.97",
"vendor_ts__quote-1.0.40",
"vendor_ts__ra_ap_base_db-0.0.300",
"vendor_ts__ra_ap_cfg-0.0.300",
"vendor_ts__ra_ap_hir-0.0.300",
"vendor_ts__ra_ap_hir_def-0.0.300",
"vendor_ts__ra_ap_hir_expand-0.0.300",
"vendor_ts__ra_ap_hir_ty-0.0.300",
"vendor_ts__ra_ap_ide_db-0.0.300",
"vendor_ts__ra_ap_intern-0.0.300",
"vendor_ts__ra_ap_load-cargo-0.0.300",
"vendor_ts__ra_ap_parser-0.0.300",
"vendor_ts__ra_ap_paths-0.0.300",
"vendor_ts__ra_ap_project_model-0.0.300",
"vendor_ts__ra_ap_span-0.0.300",
"vendor_ts__ra_ap_stdx-0.0.300",
"vendor_ts__ra_ap_syntax-0.0.300",
"vendor_ts__ra_ap_vfs-0.0.300",
"vendor_ts__rand-0.9.2",
"vendor_ts__rayon-1.11.0",
"vendor_ts__regex-1.11.3",
"vendor_ts__serde-1.0.228",
"vendor_ts__serde_json-1.0.145",
"vendor_ts__serde_with-3.14.1",
"vendor_ts__syn-2.0.106",
"vendor_ts__toml-0.9.7",
"vendor_ts__rayon-1.10.0",
"vendor_ts__regex-1.11.1",
"vendor_ts__serde-1.0.219",
"vendor_ts__serde_json-1.0.142",
"vendor_ts__serde_with-3.14.0",
"vendor_ts__syn-2.0.104",
"vendor_ts__toml-0.9.5",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.20",
"vendor_ts__tree-sitter-0.25.9",
"vendor_ts__tree-sitter-embedded-template-0.25.0",
"vendor_ts__tracing-subscriber-0.3.19",
"vendor_ts__tree-sitter-0.24.6",
"vendor_ts__tree-sitter-embedded-template-0.23.2",
"vendor_ts__tree-sitter-json-0.24.8",
"vendor_ts__tree-sitter-ql-0.23.1",
"vendor_ts__tree-sitter-ruby-0.23.1",
@@ -172,7 +172,7 @@ http_archive(
)
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
dotnet.toolchain(dotnet_version = "9.0.300")
dotnet.toolchain(dotnet_version = "9.0.100")
use_repo(dotnet, "dotnet_toolchains")
register_toolchains("@dotnet_toolchains//:all")

View File

@@ -1,4 +1,5 @@
name: "actions"
aliases: []
display_name: "GitHub Actions"
version: 0.0.1
column_kind: "utf16"
@@ -7,11 +8,9 @@ build_modes:
- none
default_queries:
- codeql/actions-queries
# Actions workflows are not reported separately by the GitHub API, so we can't
# associate them with a specific language.
file_coverage_languages: []
github_api_languages: []
scc_languages:
- YAML
scc_languages: []
file_types:
- name: workflow
display_name: GitHub Actions workflow files

View File

@@ -1,10 +0,0 @@
{
"paths": [
".github/workflows/*.yml",
".github/workflows/*.yaml",
".github/reusable_workflows/**/*.yml",
".github/reusable_workflows/**/*.yaml",
"**/action.yml",
"**/action.yaml"
]
}

View File

@@ -1,2 +0,0 @@
@echo off
type "%CODEQL_EXTRACTOR_ACTIONS_ROOT%\tools\baseline-config.json"

View File

@@ -1,3 +0,0 @@
#!/bin/sh
cat "$CODEQL_EXTRACTOR_ACTIONS_ROOT/tools/baseline-config.json"

View File

@@ -1,4 +1,3 @@
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql

View File

@@ -1,5 +1,4 @@
ql/actions/ql/src/Debug/SyntaxError.ql
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql

View File

@@ -1,4 +1,3 @@
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql

View File

@@ -1,23 +1,3 @@
## 0.4.20
No user-facing changes.
## 0.4.19
No user-facing changes.
## 0.4.18
No user-facing changes.
## 0.4.17
No user-facing changes.
## 0.4.16
No user-facing changes.
## 0.4.15
No user-facing changes.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.20
lastReleaseVersion: 0.4.15

View File

@@ -70,8 +70,8 @@ class Location extends TLocation, TBaseLocation {
/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `p`.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/

View File

@@ -261,7 +261,7 @@ class If extends AstNode instanceof IfImpl {
}
/**
* An Environment node representing a deployment environment.
* An Environemnt node representing a deployment environment.
*/
class Environment extends AstNode instanceof EnvironmentImpl {
string getName() { result = super.getName() }

View File

@@ -125,11 +125,12 @@ abstract class AstNodeImpl extends TAstNode {
* Gets the enclosing Step.
*/
StepImpl getEnclosingStep() {
this instanceof StepImpl and
result = this
or
this instanceof ScalarValueImpl and
result.getAChildNode*() = this.getParentNode()
if this instanceof StepImpl
then result = this
else
if this instanceof ScalarValueImpl
then result.getAChildNode*() = this.getParentNode()
else none()
}
/**
@@ -1415,8 +1416,9 @@ class ExternalJobImpl extends JobImpl, UsesImpl {
override string getVersion() {
exists(YamlString name |
n.lookup("uses") = name and
not name.getValue().matches("\\.%") and
result = name.getValue().regexpCapture(repoUsesParser(), 4)
if not name.getValue().matches("\\.%")
then result = name.getValue().regexpCapture(repoUsesParser(), 4)
else none()
)
}
}

View File

@@ -286,7 +286,7 @@ private module Cached {
/**
* Holds if `cfn` is the `i`th node in basic block `bb`.
*
* In other words, `i` is the shortest distance from a node `bbStart`
* In other words, `i` is the shortest distance from a node `bb`
* that starts a basic block to `cfn` along the `intraBBSucc` relation.
*/
cached

View File

@@ -3,8 +3,6 @@ private import codeql.controlflow.Cfg as CfgShared
private import codeql.Locations
module Completion {
import codeql.controlflow.SuccessorType
private newtype TCompletion =
TSimpleCompletion() or
TBooleanCompletion(boolean b) { b in [false, true] } or
@@ -27,7 +25,7 @@ module Completion {
override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) }
override DirectSuccessor getAMatchingSuccessorType() { any() }
override NormalSuccessor getAMatchingSuccessorType() { any() }
}
class BooleanCompletion extends NormalCompletion, TBooleanCompletion {
@@ -51,6 +49,34 @@ module Completion {
override ReturnSuccessor getAMatchingSuccessorType() { any() }
}
cached
private newtype TSuccessorType =
TNormalSuccessor() or
TBooleanSuccessor(boolean b) { b in [false, true] } or
TReturnSuccessor()
class SuccessorType extends TSuccessorType {
string toString() { none() }
}
class NormalSuccessor extends SuccessorType, TNormalSuccessor {
override string toString() { result = "successor" }
}
class BooleanSuccessor extends SuccessorType, TBooleanSuccessor {
boolean value;
BooleanSuccessor() { this = TBooleanSuccessor(value) }
override string toString() { result = value.toString() }
boolean getValue() { result = value }
}
class ReturnSuccessor extends SuccessorType, TReturnSuccessor {
override string toString() { result = "return" }
}
}
module CfgScope {
@@ -101,8 +127,14 @@ private module Implementation implements CfgShared::InputSig<Location> {
last(scope.(CompositeAction), e, c)
}
predicate successorTypeIsSimple(SuccessorType t) { t instanceof NormalSuccessor }
predicate successorTypeIsCondition(SuccessorType t) { t instanceof BooleanSuccessor }
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
predicate isAbnormalExitType(SuccessorType t) { none() }
int idOfAstNode(AstNode node) { none() }
int idOfCfgScope(CfgScope scope) { none() }

View File

@@ -63,10 +63,10 @@ predicate madSource(DataFlow::Node source, string kind, string fieldName) {
(
if fieldName.trim().matches("env.%")
then source.asExpr() = uses.getInScopeEnvVarExpr(fieldName.trim().replaceAll("env.", ""))
else (
fieldName.trim().matches("output.%") and
source.asExpr() = uses
)
else
if fieldName.trim().matches("output.%")
then source.asExpr() = uses
else none()
)
)
}

View File

@@ -31,14 +31,14 @@ abstract class RemoteFlowSource extends SourceNode {
class GitHubCtxSource extends RemoteFlowSource {
string flag;
string event;
GitHubExpression e;
GitHubCtxSource() {
exists(GitHubExpression e |
this.asExpr() = e and
// github.head_ref
e.getFieldName() = "head_ref" and
flag = "branch"
|
this.asExpr() = e and
// github.head_ref
e.getFieldName() = "head_ref" and
flag = "branch" and
(
event = e.getATriggerEvent().getName() and
event = "pull_request_target"
or
@@ -148,6 +148,7 @@ class GhCLICommandSource extends RemoteFlowSource, CommandSource {
class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
string cmd;
string flag;
string access_path;
Run run;
// Examples
@@ -162,7 +163,7 @@ class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
run.getScript().getACommand() = cmd and
cmd.matches("jq%") and
cmd.matches("%GITHUB_EVENT_PATH%") and
exists(string regexp, string access_path |
exists(string regexp |
untrustedEventPropertiesDataModel(regexp, flag) and
not flag = "json" and
access_path = "github.event" + cmd.regexpCapture(".*\\s+([^\\s]+)\\s+.*", 1) and

View File

@@ -19,6 +19,7 @@ abstract class ArgumentInjectionSink extends DataFlow::Node {
*/
class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
string command;
string argument;
ArgumentInjectionFromEnvVarSink() {
exists(Run run, string var |
@@ -27,7 +28,7 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
exists(run.getInScopeEnvVarExpr(var)) or
var = "GITHUB_HEAD_REF"
) and
run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, _)
run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, argument)
)
}
@@ -43,12 +44,13 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
*/
class ArgumentInjectionFromCommandSink extends ArgumentInjectionSink {
string command;
string argument;
ArgumentInjectionFromCommandSink() {
exists(CommandSource source, Run run |
run = source.getEnclosingRun() and
this.asExpr() = run.getScript() and
run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, _)
run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, argument)
)
}
@@ -100,6 +102,8 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or

View File

@@ -125,6 +125,8 @@ class LegitLabsDownloadArtifactActionStep extends UntrustedArtifactDownloadStep,
}
class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, UsesStep {
string script;
ActionsGitHubScriptDownloadStep() {
// eg:
// - uses: actions/github-script@v6
@@ -147,14 +149,12 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
// var fs = require('fs');
// fs.writeFileSync('${{github.workspace}}/test-results.zip', Buffer.from(download.data));
this.getCallee() = "actions/github-script" and
exists(string script |
this.getArgument("script") = script and
script.matches("%listWorkflowRunArtifacts(%") and
script.matches("%downloadArtifact(%") and
script.matches("%writeFileSync(%") and
// Filter out artifacts that were created by pull-request.
not script.matches("%exclude_pull_requests: true%")
)
this.getArgument("script") = script and
script.matches("%listWorkflowRunArtifacts(%") and
script.matches("%downloadArtifact(%") and
script.matches("%writeFileSync(%") and
// Filter out artifacts that were created by pull-request.
not script.matches("%exclude_pull_requests: true%")
}
override string getPath() {
@@ -171,10 +171,10 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
.getScript()
.getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else (
this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) and
result = "GITHUB_WORKSPACE/"
)
else
if this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp())
then result = "GITHUB_WORKSPACE/"
else none()
}
}
@@ -207,13 +207,12 @@ class GHRunArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
.getScript()
.getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else (
(
else
if
this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) or
this.getScript().getACommand().regexpMatch(unzipRegexp())
) and
result = "GITHUB_WORKSPACE/"
)
then result = "GITHUB_WORKSPACE/"
else none()
}
}
@@ -260,15 +259,15 @@ class DirectArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
class ArtifactPoisoningSink extends DataFlow::Node {
UntrustedArtifactDownloadStep download;
PoisonableStep poisonable;
ArtifactPoisoningSink() {
exists(PoisonableStep poisonable |
download.getAFollowingStep() = poisonable and
// excluding artifacts downloaded to the temporary directory
not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*")
|
download.getAFollowingStep() = poisonable and
// excluding artifacts downloaded to the temporary directory
not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") and
(
poisonable.(Run).getScript() = this.asExpr() and
(
// Check if the poisonable step is a local script execution step
@@ -333,6 +332,8 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or

View File

@@ -80,6 +80,8 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or

View File

@@ -159,8 +159,11 @@ abstract class CommentVsHeadDateCheck extends ControlCheck {
/* Specific implementations of control checks */
class LabelIfCheck extends LabelCheck instanceof If {
string condition;
LabelIfCheck() {
exists(string condition | condition = normalizeExpr(this.getCondition()) |
condition = normalizeExpr(this.getCondition()) and
(
// eg: contains(github.event.pull_request.labels.*.name, 'safe to test')
condition.regexpMatch(".*(^|[^!])contains\\(\\s*github\\.event\\.pull_request\\.labels\\b.*")
or

View File

@@ -130,6 +130,8 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or

View File

@@ -55,8 +55,12 @@ class EnvVarInjectionFromFileReadSink extends EnvVarInjectionSink {
* echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
*/
class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
CommandSource inCommand;
string injectedVar;
string command;
EnvVarInjectionFromCommandSink() {
exists(Run run, CommandSource inCommand, string injectedVar, string command |
exists(Run run |
this.asExpr() = inCommand.getEnclosingRun().getScript() and
run = inCommand.getEnclosingRun() and
run.getScript().getACmdReachingGitHubEnvWrite(inCommand.getCommand(), injectedVar) and
@@ -82,8 +86,12 @@ class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
* echo "FOO=$BODY" >> $GITHUB_ENV
*/
class EnvVarInjectionFromEnvVarSink extends EnvVarInjectionSink {
string inVar;
string injectedVar;
string command;
EnvVarInjectionFromEnvVarSink() {
exists(Run run, string inVar, string injectedVar, string command |
exists(Run run |
run.getScript() = this.asExpr() and
exists(run.getInScopeEnvVarExpr(inVar)) and
run.getScript().getAnEnvReachingGitHubEnvWrite(inVar, injectedVar) and
@@ -184,6 +192,8 @@ private module EnvVarInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or

View File

@@ -99,14 +99,18 @@ class OutputClobberingFromEnvVarSink extends OutputClobberingSink {
* echo $BODY
*/
class WorkflowCommandClobberingFromEnvVarSink extends OutputClobberingSink {
string clobbering_var;
string clobbered_value;
WorkflowCommandClobberingFromEnvVarSink() {
exists(Run run, string workflow_cmd_stmt, string clobbering_stmt, string clobbering_var |
exists(Run run, string workflow_cmd_stmt, string clobbering_stmt |
run.getScript() = this.asExpr() and
run.getScript().getAStmt() = clobbering_stmt and
clobbering_stmt.regexpMatch("echo\\s+(-e\\s+)?(\"|')?\\$(\\{)?" + clobbering_var + ".*") and
exists(run.getInScopeEnvVarExpr(clobbering_var)) and
run.getScript().getAStmt() = workflow_cmd_stmt and
exists(trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1)))
clobbered_value =
trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1))
)
}
}
@@ -212,6 +216,8 @@ private module OutputClobberingConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */

View File

@@ -18,6 +18,8 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */

View File

@@ -17,6 +17,8 @@ private module SecretExfiltrationConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
/** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */

View File

@@ -1,8 +1,10 @@
import actions
class UnversionedImmutableAction extends UsesStep {
string immutable_action;
UnversionedImmutableAction() {
isImmutableAction(this, _) and
isImmutableAction(this, immutable_action) and
not isSemVer(this.getVersion())
}
}

View File

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

View File

@@ -1,25 +1,3 @@
## 0.6.12
No user-facing changes.
## 0.6.11
No user-facing changes.
## 0.6.10
No user-facing changes.
## 0.6.9
### Minor Analysis Improvements
* Actions analysis now reports file coverage information on the CodeQL status page.
## 0.6.8
No user-facing changes.
## 0.6.7
No user-facing changes.

View File

@@ -1,13 +0,0 @@
/**
* @id actions/diagnostics/successfully-extracted-files
* @name Extracted files
* @description List all files that were extracted.
* @kind diagnostic
* @tags successfully-extracted-files
*/
private import codeql.Locations
from File f
where exists(f.getRelativePath())
select f, ""

View File

@@ -26,6 +26,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -36,6 +36,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -27,6 +27,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -26,6 +26,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -36,6 +36,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -27,6 +27,8 @@ private module MyConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
}
module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1
- run: |
npm install # scripts in package.json from PR would be executed here
npm install # scripts in package.json from PR would be executed here
npm build
- uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1
- run: |
npm install # scripts in package.json from PR would be executed here
npm install # scripts in package.json from PR would be executed here
npm build
- uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1
- run: |
npm install # scripts in package.json from PR would be executed here
npm install # scripts in package.json from PR would be executed here
npm build
- uses: completely/fakeaction@v2

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
## 0.6.9
### Minor Analysis Improvements
* Actions analysis now reports file coverage information on the CodeQL status page.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.12
lastReleaseVersion: 0.6.7

View File

@@ -19,5 +19,5 @@ import SecretExfiltrationFlow::PathGraph
from SecretExfiltrationFlow::PathNode source, SecretExfiltrationFlow::PathNode sink
where SecretExfiltrationFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"Potential secret exfiltration in $@, which may be leaked to an attacker-controlled resource.",
"Potential secret exfiltration in $@, which may be be leaked to an attacker-controlled resource.",
sink, sink.getNode().asExpr().(Expression).getRawExpression()

View File

@@ -37,6 +37,8 @@ where
)
or
// upload artifact is not used in the same workflow
not download.getEnclosingWorkflow().getAJob().(LocalJob).getAStep() instanceof UsesStep
not exists(UsesStep upload |
download.getEnclosingWorkflow().getAJob().(LocalJob).getAStep() = upload
)
)
select download, "Potential artifact poisoning"

View File

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

View File

@@ -3,4 +3,4 @@ nodes
| .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | semmle.label | github.event.pull_request.title |
subpaths
#select
| .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | Potential secret exfiltration in $@, which may be leaked to an attacker-controlled resource. | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | ${{ github.event.pull_request.title }} |
| .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | Potential secret exfiltration in $@, which may be be leaked to an attacker-controlled resource. | .github/workflows/test1.yml:15:11:16:75 | github.event.pull_request.title | ${{ github.event.pull_request.title }} |

View File

@@ -177,12 +177,6 @@ def insert_overlay_caller_annotations(lines):
out_lines.append(line)
return out_lines
explicitly_global = set([
"java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll",
"java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll",
"java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll",
"java/ql/lib/semmle/code/java/dispatch/internal/Unification.qll",
])
def annotate_as_appropriate(filename, lines):
'''
@@ -202,9 +196,6 @@ def annotate_as_appropriate(filename, lines):
((filename.endswith("Query.qll") or filename.endswith("Config.qll")) and
any("implements DataFlow::ConfigSig" in line for line in lines))):
return None
elif filename in explicitly_global:
# These files are explicitly global and should not be annotated.
return None
elif not any(line for line in lines if line.strip()):
return None

View File

@@ -9,7 +9,6 @@
"fragments": [
"/*- Compilations -*/",
"/*- External data -*/",
"/*- Overlay support -*/",
"/*- Files and folders -*/",
"/*- Diagnostic messages -*/",
"/*- Diagnostic messages: severity -*/",

View File

@@ -7,10 +7,12 @@ ql/cpp/ql/src/Diagnostics/ExtractedFiles.ql
ql/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
ql/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
ql/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql
ql/cpp/ql/src/Likely Bugs/Format/SnprintfOverflow.ql
ql/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.ql
ql/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
@@ -28,6 +30,7 @@ ql/cpp/ql/src/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql
ql/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
ql/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
ql/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
ql/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
ql/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
ql/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql
ql/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
@@ -40,6 +43,7 @@ ql/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql
ql/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfUniquePointerAfterLifetimeEnds.ql
ql/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
ql/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
ql/cpp/ql/src/Security/CWE/CWE-611/XXE.ql
ql/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql

View File

@@ -1,42 +1,3 @@
## 6.0.1
No user-facing changes.
## 6.0.0
### Breaking Changes
* The "Guards" libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been totally rewritten to recognize many more guards. The API remains unchanged, but the `GuardCondition` class now extends `Element` instead of `Expr`.
### New Features
* C/C++ `build-mode: none` support is now generally available.
## 5.6.1
No user-facing changes.
## 5.6.0
### Deprecated APIs
* The predicate `getAContructorCall` in the class `SslContextClass` has been deprecated. Use `getAConstructorCall` instead.
### New Features
* Added predicates `getTransitiveNumberOfVlaDimensionStmts`, `getTransitiveVlaDimensionStmt`, and `getParentVlaDecl` to `VlaDeclStmt` for handling `VlaDeclStmt`s whose base type is defined in terms of another `VlaDeclStmt` via a `typedef`.
## 5.5.0
### New Features
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.
### Minor Analysis Improvements
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.
## 5.4.1
### Minor Analysis Improvements

View File

@@ -35,7 +35,7 @@ class CustomOptions extends Options {
override predicate returnsNull(Call call) { Options.super.returnsNull(call) }
/**
* Holds if a call to the function `f` will never return.
* Holds if a call to this function will never return.
*
* By default, this holds for `exit`, `_exit`, `abort`, `__assert_fail`,
* `longjmp`, `error`, `__builtin_unreachable` and any function with a

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.

View File

@@ -1,10 +0,0 @@
## 5.5.0
### New Features
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.
### Minor Analysis Improvements
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.

View File

@@ -1,9 +0,0 @@
## 5.6.0
### Deprecated APIs
* The predicate `getAContructorCall` in the class `SslContextClass` has been deprecated. Use `getAConstructorCall` instead.
### New Features
* Added predicates `getTransitiveNumberOfVlaDimensionStmts`, `getTransitiveVlaDimensionStmt`, and `getParentVlaDecl` to `VlaDeclStmt` for handling `VlaDeclStmt`s whose base type is defined in terms of another `VlaDeclStmt` via a `typedef`.

View File

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

View File

@@ -1,9 +0,0 @@
## 6.0.0
### Breaking Changes
* The "Guards" libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been totally rewritten to recognize many more guards. The API remains unchanged, but the `GuardCondition` class now extends `Element` instead of `Expr`.
### New Features
* C/C++ `build-mode: none` support is now generally available.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 6.0.1
lastReleaseVersion: 5.4.1

View File

@@ -127,7 +127,7 @@ abstract class CryptographicAlgorithm extends CryptographicArtifact {
/**
* Normalizes a raw name into a normalized name as found in `CryptoAlgorithmNames.qll`.
* Subclassess should override for more api-specific normalization.
* By default, converts a raw name to upper-case with no hyphen, underscore, hash, or space.
* By deafult, converts a raw name to upper-case with no hyphen, underscore, hash, or space.
*/
bindingset[s]
string normalizeName(string s) {

View File

@@ -652,14 +652,14 @@ module KeyGeneration {
* Trace from EVP_PKEY_CTX* at algorithm sink to keygen,
* users can then extrapolatae the matching algorithm from the alg sink to the keygen
*/
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSizeConfig implements DataFlow::ConfigSig {
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isEVP_PKEY_CTX_Source(source, _) }
predicate isSink(DataFlow::Node sink) { isKeyGen_EVP_PKEY_CTX_Sink(sink, _) }
}
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize_Flow =
DataFlow::Global<EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSizeConfig>;
DataFlow::Global<EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize>;
/**
* UNKNOWN key sizes to general purpose key generation functions (i.e., that take in no key size and assume

View File

@@ -59,7 +59,7 @@ private string privateNormalizeFunctionName(Function f, string algType) {
*
* The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false positive functions if a directory erronously appears to be openssl;
* This may give false postive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.

View File

@@ -49,7 +49,7 @@ private string privateNormalizeFunctionName(Function f, string algType) {
*
* The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false positive functions if a directory erronously appears to be openssl;
* This may give false postive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.

View File

@@ -31,7 +31,7 @@ predicate knownPassthroughFunction(Function f, int inInd, int outInd) {
/**
* `c` is a call to a function that preserves the algorithm but changes its form.
* `inExpr` is the input argument passing through to, `outExpr` is the next expression in a dataflow step associated with `c`
* `onExpr` is the input argument passing through to, `outExpr` is the next expression in a dataflow step associated with `c`
*/
predicate knownPassthoughCall(Call c, Expr inExpr, Expr outExpr) {
exists(int inInd, int outInd |

View File

@@ -14,8 +14,8 @@ module CryptoInput implements InputSig<Language::Location> {
result = node.asExpr() or
result = node.asParameter() or
result = node.asVariable() or
result = node.asDefiningArgument() or
result = node.asIndirectExpr()
result = node.asDefiningArgument()
// TODO: do we need asIndirectExpr()?
}
string locationToFileBaseNameAndLineNumberString(Location location) {
@@ -53,7 +53,7 @@ module ArtifactFlowConfig implements DataFlow::ConfigSig {
}
}
module ArtifactFlow = TaintTracking::Global<ArtifactFlowConfig>;
module ArtifactFlow = DataFlow::Global<ArtifactFlowConfig>;
/**
* An artifact output to node input configuration
@@ -93,13 +93,7 @@ module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof OpenSslGenericSourceCandidateLiteral
{
override DataFlow::Node getOutputNode() {
// OpenSSL algorithms may be referenced either by string name or by numeric ID:
// String names (e.g. "AES-256-CBC") appear in the AST as character pointer
// literals. For these we must use `asIndirectExpr`. Numeric IDs (e.g. NID_aes_256_cbc)
// appear as integer literals. For these, we must use `asExpr` to get the "value" node.
[result.asIndirectExpr(), result.asExpr()] = this
}
override DataFlow::Node getOutputNode() { result.asExpr() = this }
override predicate flowsTo(Crypto::FlowAwareElement other) {
// TODO: separate config to avoid blowing up data-flow analysis
@@ -109,4 +103,28 @@ private class ConstantDataSource extends Crypto::GenericConstantSourceInstance i
override string getAdditionalDescription() { result = this.toString() }
}
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
}
predicate isSink(DataFlow::Node sink) {
sink = any(Crypto::FlowAwareElement other).getInputNode()
}
predicate isBarrierOut(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getInputNode()
}
predicate isBarrierIn(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getOutputNode()
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node1.(AdditionalFlowInputStep).getOutput() = node2
}
}
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
import OpenSSL.OpenSSL

View File

@@ -14,13 +14,9 @@ private import PaddingAlgorithmInstance
*/
module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
(
source.asExpr() instanceof KnownOpenSslAlgorithmExpr or
source.asIndirectExpr() instanceof KnownOpenSslAlgorithmExpr
) and
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
// No need to flow direct operations to AVCs
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall and
not source.asIndirectExpr() instanceof OpenSslDirectAlgorithmOperationCall
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall
}
predicate isSink(DataFlow::Node sink) {
@@ -50,12 +46,10 @@ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
}
module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow =
TaintTracking::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
DataFlow::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof OpenSslSpecialPaddingLiteral
}
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
predicate isSink(DataFlow::Node sink) {
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)
@@ -67,7 +61,7 @@ module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
}
module RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
TaintTracking::Global<RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
DataFlow::Global<RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }

View File

@@ -53,8 +53,7 @@ class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmIns
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)

View File

@@ -2,10 +2,12 @@ import cpp
private import experimental.quantum.Language
private import KnownAlgorithmConstants
private import Crypto::KeyOpAlg as KeyOpAlg
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import OpenSSLAlgorithmInstances
private import OpenSSLAlgorithmInstanceBase
private import PaddingAlgorithmInstance
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import AlgToAVCFlow
private import BlockAlgorithmInstance
/**
* Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type.
@@ -77,8 +79,7 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
@@ -96,13 +97,10 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
}
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() {
//TODO: the padding is either self, or it flows through getter ctx to a set padding call
// like EVP_PKEY_CTX_set_rsa_padding
result = this
or
exists(OperationStep s |
this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and
s.getAlgorithmValueConsumerForInput(PaddingAlgorithmIO()) =
result.(OpenSslAlgorithmInstance).getAvc()
)
// TODO or trace through getter ctx to set padding
}
override string getRawAlgorithmName() {
@@ -119,7 +117,7 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
knownOpenSslConstantToCipherFamilyType(this, result)
or
not knownOpenSslConstantToCipherFamilyType(this, _) and
result = Crypto::KeyOpAlg::TOtherKeyOperationAlgorithmType()
result = Crypto::KeyOpAlg::TUnknownKeyOperationAlgorithmType()
}
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }

View File

@@ -21,8 +21,7 @@ class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorith
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
@@ -40,7 +39,7 @@ class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorith
result = this.(Call).getTarget().getName()
}
override Crypto::EllipticCurveType getEllipticCurveType() {
override Crypto::EllipticCurveFamilyType getEllipticCurveFamilyType() {
if
Crypto::ellipticCurveNameToKnownKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _,
_)

View File

@@ -59,8 +59,7 @@ class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
@@ -72,7 +71,7 @@ class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::THashType getHashType() {
override Crypto::THashType getHashFamily() {
knownOpenSslConstantToHashFamilyType(this, result)
or
not knownOpenSslConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()

View File

@@ -37,8 +37,7 @@ class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithm
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)

View File

@@ -171,15 +171,9 @@ class KnownOpenSslKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSsl
}
predicate knownOpenSslAlgorithmOperationCall(Call c, string normalized, string algType) {
c.getTarget().getName() in [
"EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new", "RSA_sign", "RSA_verify"
] and
c.getTarget().getName() in ["EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new"] and
normalized = "RSA" and
algType = "ASYMMETRIC_ENCRYPTION"
or
c.getTarget().getName() in ["DSA_do_sign", "DSA_do_verify"] and
normalized = "DSA" and
algType = "SIGNATURE"
}
/**

View File

@@ -2,13 +2,12 @@ import cpp
private import experimental.quantum.Language
private import KnownAlgorithmConstants
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations
private import Crypto::KeyOpAlg as KeyOpAlg
private import AlgToAVCFlow
class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
Crypto::MacAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
{
OpenSslAlgorithmValueConsumer getterCall;
@@ -22,8 +21,7 @@ class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
@@ -35,34 +33,17 @@ class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override string getRawAlgorithmName() {
override string getRawMacAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override Crypto::KeyOpAlg::AlgorithmType getAlgorithmType() {
if this instanceof KnownOpenSslHMacAlgorithmExpr
then result = KeyOpAlg::TMac(KeyOpAlg::HMAC())
else
if this instanceof KnownOpenSslCMacAlgorithmExpr
then result = KeyOpAlg::TMac(KeyOpAlg::CMAC())
else result = KeyOpAlg::TMac(KeyOpAlg::OtherMacAlgorithmType())
override Crypto::MacType getMacType() {
this instanceof KnownOpenSslHMacAlgorithmExpr and result = Crypto::HMAC()
or
this instanceof KnownOpenSslCMacAlgorithmExpr and result = Crypto::CMAC()
}
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
// TODO: trace to any key size initializer?
none()
}
override int getKeySizeFixed() {
// TODO: are there known fixed key sizes to consider?
none()
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
}
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmInstance,
@@ -79,13 +60,9 @@ class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HmacAlgorithmIns
// where the current AVC traces to a HashAlgorithmIO consuming operation step.
// TODO: need to consider getting reset values, tracing down to the first set for now
exists(OperationStep s, AvcContextCreationStep avc |
avc = super.getAvc() and
avc = this.getAvc() and
avc.flowsToOperationStep(s) and
s.getAlgorithmValueConsumerForInput(HashAlgorithmIO()) = result
)
}
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
}

View File

@@ -1,10 +1,10 @@
import cpp
private import experimental.quantum.Language
private import OpenSSLAlgorithmInstanceBase
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
private import AlgToAVCFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as KeyOpAlg
/**
@@ -18,14 +18,13 @@ private import codeql.quantum.experimental.Standardization::Types::KeyOpAlg as K
* # define RSA_PKCS1_WITH_TLS_PADDING 7
* # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
*/
class OpenSslSpecialPaddingLiteral extends Literal {
class OpenSslPaddingLiteral extends Literal {
// TODO: we can be more specific about where the literal is in a larger expression
// to avoid literals that are clealy not representing an algorithm, e.g., array indices.
OpenSslSpecialPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
OpenSslPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
}
/**
* Holds if `e` has the given `type`.
* Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
@@ -46,6 +45,9 @@ predicate knownOpenSslConstantToPaddingFamilyType(
)
}
//abstract class OpenSslPaddingAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
// TODO: need to alter this to include known padding constants which don't have the
// same mechanics as those with known nids
class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::PaddingAlgorithmInstance instanceof Expr
{
@@ -64,8 +66,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
isPaddingSpecificConsumer = false
@@ -78,13 +79,12 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
isPaddingSpecificConsumer = false
or
// Possibility 3: padding-specific literal
this instanceof OpenSslSpecialPaddingLiteral and
this instanceof OpenSslPaddingLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a padding-specific consumer
RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow::flow(src, sink)
) and
@@ -124,6 +124,44 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
}
}
// // Values used for EVP_PKEY_CTX_set_rsa_padding, these are
// // not the same as 'typical' constants found in the set of known algorithm constants
// // they do not have an NID
// // TODO: what about setting the padding directly?
// class KnownRSAPaddingConstant extends OpenSslPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
// {
// KnownRSAPaddingConstant() {
// // from rsa.h in openssl:
// // # define RSA_PKCS1_PADDING 1
// // # define RSA_NO_PADDING 3
// // # define RSA_PKCS1_OAEP_PADDING 4
// // # define RSA_X931_PADDING 5
// // /* EVP_PKEY_ only */
// // # define RSA_PKCS1_PSS_PADDING 6
// // # define RSA_PKCS1_WITH_TLS_PADDING 7
// // /* internal RSA_ only */
// // # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
// this instanceof Literal and
// this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8]
// // TODO: trace to padding-specific consumers
// RsaPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow
// }
// override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() }
// override Crypto::TPaddingType getPaddingType() {
// if this.(Literal).getValue().toInt() in [1, 6, 7, 8]
// then result = Crypto::PKCS1_v1_5()
// else
// if this.(Literal).getValue().toInt() = 3
// then result = Crypto::NoPadding()
// else
// if this.(Literal).getValue().toInt() = 4
// then result = Crypto::OAEP()
// else
// if this.(Literal).getValue().toInt() = 5
// then result = Crypto::ANSI_X9_23()
// else result = Crypto::OtherPadding()
// }
// }
class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance,
KnownOpenSslPaddingConstantAlgorithmInstance
{
@@ -132,18 +170,10 @@ class OaepPaddingAlgorithmInstance extends Crypto::OaepPaddingAlgorithmInstance,
}
override Crypto::HashAlgorithmInstance getOaepEncodingHashAlgorithm() {
exists(OperationStep s |
this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and
s.getAlgorithmValueConsumerForInput(HashAlgorithmOaepIO()) =
result.(OpenSslAlgorithmInstance).getAvc()
)
none() //TODO
}
override Crypto::HashAlgorithmInstance getMgf1HashAlgorithm() {
exists(OperationStep s |
this.getAvc().(AvcContextCreationStep).flowsToOperationStep(s) and
s.getAlgorithmValueConsumerForInput(HashAlgorithmMgf1IO()) =
result.(OpenSslAlgorithmInstance).getAvc()
)
none() //TODO
}
}

View File

@@ -47,8 +47,7 @@ class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmIns
// Sink is an argument to a signature getter call
sink = getterCall.getInputNode() and
// Source is `this`
// NOTE: src literals can be ints or strings, so need to consider asExpr and asIndirectExpr
this = [src.asExpr(), src.asIndirectExpr()] and
src.asExpr() = this and
// This traces to a getter
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)

View File

@@ -12,17 +12,15 @@ class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
DataFlow::Node resultNode;
EvpCipherAlgorithmValueConsumer() {
resultNode.asIndirectExpr() = this and
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() in ["EVP_get_cipherbyname", "EVP_get_cipherbyobj"] and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(0)
or
this.(Call).getTarget().getName() = "EVP_get_cipherbynid" and
// algorithm is an NID (int), use asExpr()
this.(Call).getTarget().getName() in [
"EVP_get_cipherbyname", "EVP_get_cipherbyobj", "EVP_get_cipherbynid"
] and
valueArgNode.asExpr() = this.(Call).getArgument(0)
or
this.(Call).getTarget().getName() in ["EVP_CIPHER_fetch", "EVP_ASYM_CIPHER_fetch"] and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(1)
valueArgNode.asExpr() = this.(Call).getArgument(1)
)
}

View File

@@ -23,7 +23,7 @@ class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanc
*/
override DataFlow::Node getResultNode() {
this instanceof OpenSslDirectAlgorithmFetchCall and
result.asIndirectExpr() = this
result.asExpr() = this
// NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated
// the algorithm is directly used
}

View File

@@ -12,19 +12,14 @@ class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
DataFlow::Node resultNode;
EvpEllipticCurveAlgorithmConsumer() {
resultNode.asIndirectExpr() = this.(Call) and // in all cases the result is the return
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
(
this.(Call).getTarget().getName() = "EVP_EC_gen" and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(0)
or
this.(Call).getTarget().getName() = "EC_KEY_new_by_curve_name" and
// algorithm is an NID (int), use asExpr()
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
valueArgNode.asExpr() = this.(Call).getArgument(0)
or
this.(Call).getTarget().getName() in [
"EC_KEY_new_by_curve_name_ex", "EVP_PKEY_CTX_set_ec_paramgen_curve_nid"
] and
// algorithm is an NID (int), use asExpr
valueArgNode.asExpr() = this.(Call).getArgument(2)
)
}

View File

@@ -9,11 +9,11 @@ abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer
/**
* An EVP_Q_Digest directly consumes algorithm constant values
*/
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer instanceof Call {
Evp_Q_Digest_Algorithm_Consumer() { super.getTarget().getName() = "EVP_Q_digest" }
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
override Crypto::ConsumerInputDataFlowNode getInputNode() {
result.asIndirectExpr() = super.getArgument(1)
result.asExpr() = this.(Call).getArgument(1)
}
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
@@ -42,7 +42,7 @@ class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
"EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_oaep_md_name",
"EVP_PKEY_CTX_set_dsa_paramgen_md_props"
] and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(1)
valueArgNode.asExpr() = this.(Call).getArgument(1)
}
override DataFlow::Node getResultNode() { none() }
@@ -64,18 +64,18 @@ class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
DataFlow::Node resultNode;
EvpDigestAlgorithmValueConsumer() {
resultNode.asIndirectExpr() = this and
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() in [
"EVP_get_digestbyname", "EVP_get_digestbynid", "EVP_get_digestbyobj"
] and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(0)
valueArgNode.asExpr() = this.(Call).getArgument(0)
or
this.(Call).getTarget().getName() = "EVP_MD_fetch" and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(1)
valueArgNode.asExpr() = this.(Call).getArgument(1)
or
this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(2)
valueArgNode.asExpr() = this.(Call).getArgument(2)
)
}
@@ -87,21 +87,3 @@ class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}
class RsaSignOrVerifyHashAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
RsaSignOrVerifyHashAlgorithmValueConsumer() {
this.(Call).getTarget().getName() in ["RSA_sign", "RSA_verify"] and
// arg 0 is an int, use asExpr
valueArgNode.asExpr() = this.(Call).getArgument(0)
}
override DataFlow::Node getResultNode() { none() }
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}

View File

@@ -11,10 +11,10 @@ class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer {
DataFlow::Node resultNode;
EvpKemAlgorithmValueConsumer() {
resultNode.asIndirectExpr() = this and
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() = "EVP_KEM_fetch" and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(1)
valueArgNode.asExpr() = this.(Call).getArgument(1)
)
}

View File

@@ -11,10 +11,10 @@ class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueCons
DataFlow::Node resultNode;
EvpKeyExchangeAlgorithmValueConsumer() {
resultNode.asIndirectExpr() = this and
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and
valueArgNode.asIndirectExpr() = this.(Call).getArgument(1)
valueArgNode.asExpr() = this.(Call).getArgument(1)
)
}

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