mirror of
https://github.com/github/codeql.git
synced 2026-05-14 11:19:27 +02:00
Merge branch 'main' into fix/path-injection-torealpath
This commit is contained in:
@@ -27,7 +27,7 @@ bazel_dep(name = "abseil-cpp", version = "20260107.1", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.2.2-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.47.0")
|
||||
bazel_dep(name = "gazelle", version = "0.50.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
|
||||
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
|
||||
bazel_dep(name = "rules_rust", version = "0.69.0")
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.4.34
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.
|
||||
|
||||
## 0.4.33
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.32
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/lib/change-notes/released/0.4.33.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.33.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.33
|
||||
|
||||
No user-facing changes.
|
||||
5
actions/ql/lib/change-notes/released/0.4.34.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.34.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.34
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.32
|
||||
lastReleaseVersion: 0.4.34
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: actionsSinkModel
|
||||
data:
|
||||
- ["docker/build-push-action", "*", "input.context", "code-injection", "manual"]
|
||||
@@ -1,6 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: actionsSinkModel
|
||||
data:
|
||||
- ["step-security/harden-runner", "*", "input.allowed-endpoints", "command-injection", "manual"]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.33-dev
|
||||
version: 0.4.35-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
## 0.6.26
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
|
||||
|
||||
## 0.6.25
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.24
|
||||
|
||||
No user-facing changes.
|
||||
@@ -159,7 +173,7 @@ No user-facing changes.
|
||||
* `actions/if-expression-always-true/critical`
|
||||
* `actions/if-expression-always-true/high`
|
||||
* `actions/unnecessary-use-of-advanced-config`
|
||||
|
||||
|
||||
* The following query has been moved from the `code-scanning` suite to the `security-extended`
|
||||
suite. Any existing alerts for this query will be closed automatically unless the analysis is
|
||||
configured to use the `security-extended` suite.
|
||||
|
||||
@@ -26,10 +26,23 @@ string permissionsForJob(Job job) {
|
||||
"{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}"
|
||||
}
|
||||
|
||||
predicate jobHasPermissions(Job job) {
|
||||
exists(job.getPermissions())
|
||||
or
|
||||
exists(job.getEnclosingWorkflow().getPermissions())
|
||||
or
|
||||
// The workflow is reusable and cannot be triggered in any other way; check callers
|
||||
exists(ReusableWorkflow r | r = job.getEnclosingWorkflow() |
|
||||
not exists(Event e | e = r.getOn().getAnEvent() | e.getName() != "workflow_call") and
|
||||
forall(Job caller | caller = job.getEnclosingWorkflow().(ReusableWorkflow).getACaller() |
|
||||
jobHasPermissions(caller)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from Job job, string permissions
|
||||
where
|
||||
not exists(job.getPermissions()) and
|
||||
not exists(job.getEnclosingWorkflow().getPermissions()) and
|
||||
not jobHasPermissions(job) and
|
||||
// exists a trigger event that is not a workflow_call
|
||||
exists(Event e |
|
||||
e = job.getATriggerEvent() and
|
||||
|
||||
@@ -20,6 +20,6 @@ from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sin
|
||||
where
|
||||
ArtifactPoisoningFlow::flowPath(source, sink) and
|
||||
event = getRelevantEventInPrivilegedContext(sink.getNode())
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential artifact poisoning in $@, which may be controlled by an external user ($@).", sink,
|
||||
sink.getNode().toString(), event, event.getName()
|
||||
select source.getNode(), source, sink,
|
||||
"Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@).",
|
||||
event, event.getName()
|
||||
|
||||
@@ -20,6 +20,5 @@ from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sin
|
||||
where
|
||||
ArtifactPoisoningFlow::flowPath(source, sink) and
|
||||
inNonPrivilegedContext(sink.getNode().asExpr())
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential artifact poisoning in $@, which may be controlled by an external user.", sink,
|
||||
sink.getNode().toString()
|
||||
select source.getNode(), source, sink,
|
||||
"Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user."
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.25.md
Normal file
3
actions/ql/src/change-notes/released/0.6.25.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.25
|
||||
|
||||
No user-facing changes.
|
||||
9
actions/ql/src/change-notes/released/0.6.26.md
Normal file
9
actions/ql/src/change-notes/released/0.6.26.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 0.6.26
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.24
|
||||
lastReleaseVersion: 0.6.26
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.25-dev
|
||||
version: 0.6.27-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
9
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms11.yml
vendored
Normal file
9
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms11.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/deploy-pages
|
||||
11
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms12.yml
vendored
Normal file
11
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms12.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
pages: write
|
||||
|
||||
jobs:
|
||||
call-workflow:
|
||||
uses: ./.github/workflows/perms11.yml
|
||||
@@ -55,21 +55,21 @@ nodes
|
||||
| .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | semmle.label | ./gradlew buildScanPublishPrevious\n |
|
||||
subpaths
|
||||
#select
|
||||
| .github/workflows/artifactpoisoning11.yml:38:11:38:77 | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | .github/workflows/artifactpoisoning11.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning11.yml:38:11:38:77 | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning11.yml:38:11:38:77 | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | .github/workflows/artifactpoisoning11.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning12.yml:38:11:38:25 | python foo/x.py | .github/workflows/artifactpoisoning12.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning12.yml:38:11:38:25 | python foo/x.py | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning12.yml:38:11:38:25 | python foo/x.py | python foo/x.py | .github/workflows/artifactpoisoning12.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning21.yml:19:14:20:21 | sh foo/cmd\n | .github/workflows/artifactpoisoning21.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning21.yml:19:14:20:21 | sh foo/cmd\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning21.yml:19:14:20:21 | sh foo/cmd\n | sh foo/cmd\n | .github/workflows/artifactpoisoning21.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning22.yml:18:14:18:19 | sh cmd | .github/workflows/artifactpoisoning22.yml:13:9:17:6 | Uses Step | .github/workflows/artifactpoisoning22.yml:18:14:18:19 | sh cmd | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning22.yml:18:14:18:19 | sh cmd | sh cmd | .github/workflows/artifactpoisoning22.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning31.yml:19:14:19:22 | ./foo/cmd | .github/workflows/artifactpoisoning31.yml:13:9:15:6 | Run Step | .github/workflows/artifactpoisoning31.yml:19:14:19:22 | ./foo/cmd | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning31.yml:19:14:19:22 | ./foo/cmd | ./foo/cmd | .github/workflows/artifactpoisoning31.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning32.yml:17:14:18:20 | ./bar/cmd\n | .github/workflows/artifactpoisoning32.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning32.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning32.yml:17:14:18:20 | ./bar/cmd\n | ./bar/cmd\n | .github/workflows/artifactpoisoning32.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning33.yml:17:14:18:20 | ./bar/cmd\n | .github/workflows/artifactpoisoning33.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning33.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning33.yml:17:14:18:20 | ./bar/cmd\n | ./bar/cmd\n | .github/workflows/artifactpoisoning33.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning34.yml:20:14:22:23 | npm install\nnpm run lint\n | .github/workflows/artifactpoisoning34.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning34.yml:20:14:22:23 | npm install\nnpm run lint\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning34.yml:20:14:22:23 | npm install\nnpm run lint\n | npm install\nnpm run lint\n | .github/workflows/artifactpoisoning34.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning41.yml:22:14:22:22 | ./foo/cmd | .github/workflows/artifactpoisoning41.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning41.yml:22:14:22:22 | ./foo/cmd | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning41.yml:22:14:22:22 | ./foo/cmd | ./foo/cmd | .github/workflows/artifactpoisoning41.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | ./cmd | .github/workflows/artifactpoisoning42.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | sed -f config foo.md > bar.md\n | .github/workflows/artifactpoisoning71.yml:4:5:4:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | python test.py | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Uses Step | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | make snapshot | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | npm install | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/test18.yml:36:15:40:58 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Uses Step | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
| .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning11.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning11.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning11.yml:38:11:38:77 | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning11.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning12.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning12.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning12.yml:38:11:38:25 | python foo/x.py | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning12.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning21.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning21.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning21.yml:19:14:20:21 | sh foo/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning21.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning22.yml:13:9:17:6 | Uses Step | .github/workflows/artifactpoisoning22.yml:13:9:17:6 | Uses Step | .github/workflows/artifactpoisoning22.yml:18:14:18:19 | sh cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning22.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning31.yml:13:9:15:6 | Run Step | .github/workflows/artifactpoisoning31.yml:13:9:15:6 | Run Step | .github/workflows/artifactpoisoning31.yml:19:14:19:22 | ./foo/cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning31.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning32.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning32.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning32.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning32.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning33.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning33.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning33.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning33.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning34.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning34.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning34.yml:20:14:22:23 | npm install\nnpm run lint\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning34.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning41.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning41.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning41.yml:22:14:22:22 | ./foo/cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning41.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning42.yml:4:3:4:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning71.yml:4:5:4:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
## 10.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
|
||||
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.
|
||||
|
||||
## 9.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
|
||||
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
|
||||
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
|
||||
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
|
||||
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
|
||||
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
|
||||
* Added dataflow through members initialized via non-static data member initialization (NSDMI).
|
||||
|
||||
## 8.0.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/).
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
|
||||
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
|
||||
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added dataflow through members initialized via non-static data member initialization (NSDMI).
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
|
||||
10
cpp/ql/lib/change-notes/released/10.0.0.md
Normal file
10
cpp/ql/lib/change-notes/released/10.0.0.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 10.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
|
||||
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.
|
||||
19
cpp/ql/lib/change-notes/released/9.0.0.md
Normal file
19
cpp/ql/lib/change-notes/released/9.0.0.md
Normal file
@@ -0,0 +1,19 @@
|
||||
## 9.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
|
||||
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
|
||||
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
|
||||
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
|
||||
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
|
||||
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
|
||||
* Added dataflow through members initialized via non-static data member initialization (NSDMI).
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 8.0.3
|
||||
lastReleaseVersion: 10.0.0
|
||||
|
||||
@@ -12,4 +12,7 @@ extensions:
|
||||
- ["", "", False, "_malloca", "0", "", "", False]
|
||||
- ["", "", False, "calloc", "1", "0", "", True]
|
||||
- ["std", "", False, "calloc", "1", "0", "", True]
|
||||
- ["bsl", "", False, "calloc", "1", "0", "", True]
|
||||
- ["bsl", "", False, "calloc", "1", "0", "", True]
|
||||
- ["", "", False, "aligned_alloc", "1", "", "", True]
|
||||
- ["std", "", False, "aligned_alloc", "1", "", "", True]
|
||||
- ["bsl", "", False, "aligned_alloc", "1", "", "", True]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 8.0.4-dev
|
||||
version: 10.0.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -42,3 +42,10 @@ class MesonPrivateTestFile extends ConfigurationTestFile {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file created by a GNU autoconf configure script to test the system configuration.
|
||||
*/
|
||||
class AutoconfConfigureTestFile extends ConfigurationTestFile {
|
||||
AutoconfConfigureTestFile() { this.getBaseName().regexpMatch("conftest[0-9]*\\.c(pp)?") }
|
||||
}
|
||||
|
||||
@@ -459,6 +459,13 @@ class FormatLiteral extends Literal instanceof StringLiteral {
|
||||
*/
|
||||
int getConvSpecOffset(int n) { result = this.getFormat().indexOf("%", n, 0) }
|
||||
|
||||
/**
|
||||
* Gets the nth conversion specifier string.
|
||||
*/
|
||||
private string getConvSpecString(int n) {
|
||||
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
|
||||
}
|
||||
|
||||
/*
|
||||
* Each of these predicates gets a regular expressions to match each individual
|
||||
* parts of a conversion specifier.
|
||||
@@ -524,22 +531,20 @@ class FormatLiteral extends Literal instanceof StringLiteral {
|
||||
int n, string spec, string params, string flags, string width, string prec, string len,
|
||||
string conv
|
||||
) {
|
||||
exists(int offset, string fmt, string rst, string regexp |
|
||||
offset = this.getConvSpecOffset(n) and
|
||||
fmt = this.getFormat() and
|
||||
rst = fmt.substring(offset, fmt.length()) and
|
||||
exists(string convSpec, string regexp |
|
||||
convSpec = this.getConvSpecString(n) and
|
||||
regexp = this.getConvSpecRegexp() and
|
||||
(
|
||||
spec = rst.regexpCapture(regexp, 1) and
|
||||
params = rst.regexpCapture(regexp, 2) and
|
||||
flags = rst.regexpCapture(regexp, 3) and
|
||||
width = rst.regexpCapture(regexp, 4) and
|
||||
prec = rst.regexpCapture(regexp, 5) and
|
||||
len = rst.regexpCapture(regexp, 6) and
|
||||
conv = rst.regexpCapture(regexp, 7)
|
||||
spec = convSpec.regexpCapture(regexp, 1) and
|
||||
params = convSpec.regexpCapture(regexp, 2) and
|
||||
flags = convSpec.regexpCapture(regexp, 3) and
|
||||
width = convSpec.regexpCapture(regexp, 4) and
|
||||
prec = convSpec.regexpCapture(regexp, 5) and
|
||||
len = convSpec.regexpCapture(regexp, 6) and
|
||||
conv = convSpec.regexpCapture(regexp, 7)
|
||||
or
|
||||
spec = rst.regexpCapture(regexp, 1) and
|
||||
not exists(rst.regexpCapture(regexp, 2)) and
|
||||
spec = convSpec.regexpCapture(regexp, 1) and
|
||||
not exists(convSpec.regexpCapture(regexp, 2)) and
|
||||
params = "" and
|
||||
flags = "" and
|
||||
width = "" and
|
||||
@@ -554,12 +559,10 @@ class FormatLiteral extends Literal instanceof StringLiteral {
|
||||
* Gets the nth conversion specifier (including the initial `%`).
|
||||
*/
|
||||
string getConvSpec(int n) {
|
||||
exists(int offset, string fmt, string rst, string regexp |
|
||||
offset = this.getConvSpecOffset(n) and
|
||||
fmt = this.getFormat() and
|
||||
rst = fmt.substring(offset, fmt.length()) and
|
||||
exists(string convSpec, string regexp |
|
||||
convSpec = this.getConvSpecString(n) and
|
||||
regexp = this.getConvSpecRegexp() and
|
||||
result = rst.regexpCapture(regexp, 1)
|
||||
result = convSpec.regexpCapture(regexp, 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +194,13 @@ class ScanfFormatLiteral extends Expr {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nth conversion specifier string.
|
||||
*/
|
||||
private string getConvSpecString(int n) {
|
||||
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the regular expression to match each individual part of a conversion specifier.
|
||||
*/
|
||||
@@ -227,16 +234,14 @@ class ScanfFormatLiteral extends Expr {
|
||||
* specifier.
|
||||
*/
|
||||
predicate parseConvSpec(int n, string spec, string width, string len, string conv) {
|
||||
exists(int offset, string fmt, string rst, string regexp |
|
||||
offset = this.getConvSpecOffset(n) and
|
||||
fmt = this.getFormat() and
|
||||
rst = fmt.substring(offset, fmt.length()) and
|
||||
exists(string convSpec, string regexp |
|
||||
convSpec = this.getConvSpecString(n) and
|
||||
regexp = this.getConvSpecRegexp() and
|
||||
(
|
||||
spec = rst.regexpCapture(regexp, 1) and
|
||||
width = rst.regexpCapture(regexp, 2) and
|
||||
len = rst.regexpCapture(regexp, 3) and
|
||||
conv = rst.regexpCapture(regexp, 4)
|
||||
spec = convSpec.regexpCapture(regexp, 1) and
|
||||
width = convSpec.regexpCapture(regexp, 2) and
|
||||
len = convSpec.regexpCapture(regexp, 3) and
|
||||
conv = convSpec.regexpCapture(regexp, 4)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
*
|
||||
* The extensible relations have the following columns:
|
||||
* - Sources:
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind`
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
|
||||
* - Sinks:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; kind`
|
||||
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
|
||||
* - Summaries:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
|
||||
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
|
||||
* - Barriers:
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
|
||||
* - BarrierGuards:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance`
|
||||
*
|
||||
* The interpretation of a row is similar to API-graphs with a left-to-right
|
||||
* reading.
|
||||
@@ -87,11 +91,23 @@
|
||||
* value, and
|
||||
* - flow from the _second_ indirection of the 0th argument to the first
|
||||
* indirection of the return value, etc.
|
||||
* 8. The `kind` column is a tag that can be referenced from QL to determine to
|
||||
* 8. The `acceptingValue` column of barrier guard models specifies the condition
|
||||
* under which the guard blocks flow. It can be one of "true" or "false". In
|
||||
* the future "no-exception", "not-zero", "null", "not-null" may be supported.
|
||||
* 9. The `kind` column is a tag that can be referenced from QL to determine to
|
||||
* which classes the interpreted elements should be added. For example, for
|
||||
* sources "remote" indicates a default remote flow source, and for summaries
|
||||
* "taint" indicates a default additional taint step and "value" indicates a
|
||||
* globally applicable value-preserving step.
|
||||
* 10. The `provenance` column is a tag to indicate the origin and verification of a model.
|
||||
* The format is {origin}-{verification} or just "manual" where the origin describes
|
||||
* the origin of the model and verification describes how the model has been verified.
|
||||
* Some examples are:
|
||||
* - "df-generated": The model has been generated by the model generator tool.
|
||||
* - "df-manual": The model has been generated by the model generator and verified by a human.
|
||||
* - "manual": The model has been written by hand.
|
||||
* This information is used in a heuristic for dataflow analysis to determine, if a
|
||||
* model or source code should be used for determining flow.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
@@ -931,13 +947,13 @@ private module Cached {
|
||||
|
||||
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
|
||||
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingValue,
|
||||
string kind, string model
|
||||
|
|
||||
isBarrierGuardNode(n, acceptingvalue, kind, model) and
|
||||
isBarrierGuardNode(n, acceptingValue, kind, model) and
|
||||
n.asNode().asExpr() = e and
|
||||
kmp = TMkPair(kind, model) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
|
||||
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
@@ -954,14 +970,14 @@ private module Cached {
|
||||
) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode interpretNode,
|
||||
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
|
||||
Public::AcceptingValue acceptingValue, string kind, string model, int indirectionIndex,
|
||||
Private::ArgumentNode arg
|
||||
|
|
||||
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
|
||||
isBarrierGuardNode(interpretNode, acceptingValue, kind, model) and
|
||||
arg = interpretNode.asNode() and
|
||||
arg.asIndirectExpr(indirectionIndex) = e and
|
||||
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
|
||||
arg.getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ extensible predicate barrierModel(
|
||||
*/
|
||||
extensible predicate barrierGuardModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
|
||||
string input, string acceptingValue, string kind, string provenance, QlBuiltins::ExtensionId madId
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -162,13 +162,13 @@ module SourceSinkInterpretationInput implements
|
||||
}
|
||||
|
||||
predicate barrierGuardElement(
|
||||
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
|
||||
Element e, string input, Public::AcceptingValue acceptingValue, string kind,
|
||||
Public::Provenance provenance, string model
|
||||
) {
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
|
||||
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingValue, kind,
|
||||
provenance, model) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext)
|
||||
)
|
||||
|
||||
@@ -11,10 +11,3 @@ import semmle.code.cpp.models.Models
|
||||
* The function may still raise a structured exception handling (SEH) exception.
|
||||
*/
|
||||
abstract class NonCppThrowingFunction extends Function { }
|
||||
|
||||
/**
|
||||
* A function that is guaranteed to never throw.
|
||||
*
|
||||
* DEPRECATED: use `NonCppThrowingFunction` instead.
|
||||
*/
|
||||
deprecated class NonThrowingFunction = NonCppThrowingFunction;
|
||||
|
||||
@@ -10,19 +10,6 @@ import semmle.code.cpp.Function
|
||||
import semmle.code.cpp.models.Models
|
||||
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
|
||||
|
||||
/**
|
||||
* A function that is known to raise an exception.
|
||||
*
|
||||
* DEPRECATED: use `AlwaysSehThrowingFunction` instead.
|
||||
*/
|
||||
abstract deprecated class ThrowingFunction extends Function {
|
||||
/**
|
||||
* Holds if this function may throw an exception during evaluation.
|
||||
* If `unconditional` is `true` the function always throws an exception.
|
||||
*/
|
||||
abstract predicate mayThrowException(boolean unconditional);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that unconditionally raises a structured exception handling (SEH) exception.
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
## 1.6.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
|
||||
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
|
||||
|
||||
## 1.6.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
|
||||
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
|
||||
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
|
||||
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
|
||||
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
|
||||
|
||||
## 1.5.15
|
||||
|
||||
No user-facing changes.
|
||||
@@ -341,7 +366,7 @@ No user-facing changes.
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives.
|
||||
* Added dataflow models for the `gettext` function variants.
|
||||
* Added dataflow models for the `gettext` function variants.
|
||||
|
||||
## 0.9.4
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 8.1
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/integer-multiplication-cast-to-long
|
||||
* @tags reliability
|
||||
* security
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @security-severity 7.5
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/wrong-type-format-argument
|
||||
* @tags reliability
|
||||
* correctness
|
||||
|
||||
@@ -14,6 +14,9 @@ function may behave unpredictably.</p>
|
||||
<p>This may indicate a misspelled function name, or that the required header containing
|
||||
the function declaration has not been included.</p>
|
||||
|
||||
<p>Note: This query is not compatible with <code>build mode: none</code> databases, and produces
|
||||
no results on those databases.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Provide an explicit declaration of the function before invoking it.</p>
|
||||
@@ -26,4 +29,4 @@ the function declaration has not been included.</p>
|
||||
<references>
|
||||
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL31-C.+Declare+identifiers+before+using+them">DCL31-C. Declare identifiers before using them</a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
</qhelp>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* may lead to unpredictable behavior.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/implicit-function-declaration
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
@@ -17,6 +17,11 @@ import TooFewArguments
|
||||
import TooManyArguments
|
||||
import semmle.code.cpp.commons.Exclusions
|
||||
|
||||
/*
|
||||
* This query is not compatible with build mode: none databases, and produces
|
||||
* no results on those databases.
|
||||
*/
|
||||
|
||||
predicate locInfo(Locatable e, File file, int line, int col) {
|
||||
e.getFile() = file and
|
||||
e.getLocation().getStartLine() = line and
|
||||
@@ -39,6 +44,7 @@ predicate isCompiledAsC(File f) {
|
||||
from FunctionDeclarationEntry fdeIm, FunctionCall fc
|
||||
where
|
||||
isCompiledAsC(fdeIm.getFile()) and
|
||||
not any(Compilation c).buildModeNone() and
|
||||
not isFromMacroDefinition(fc) and
|
||||
fdeIm.isImplicit() and
|
||||
sameLocation(fdeIm, fc) and
|
||||
|
||||
@@ -79,9 +79,7 @@ private predicate hasZeroParamDecl(Function f) {
|
||||
|
||||
// True if this file (or header) was compiled as a C file
|
||||
private predicate isCompiledAsC(File f) {
|
||||
f.compiledAsC()
|
||||
or
|
||||
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
|
||||
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
|
||||
}
|
||||
|
||||
predicate mistypedFunctionArguments(FunctionCall fc, Function f, Parameter p) {
|
||||
|
||||
@@ -28,9 +28,7 @@ private predicate hasZeroParamDecl(Function f) {
|
||||
|
||||
/* Holds if this file (or header) was compiled as a C file. */
|
||||
private predicate isCompiledAsC(File f) {
|
||||
f.compiledAsC()
|
||||
or
|
||||
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
|
||||
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
|
||||
}
|
||||
|
||||
/** Holds if `fc` is a call to `f` with too few arguments. */
|
||||
|
||||
@@ -19,9 +19,7 @@ private predicate hasZeroParamDecl(Function f) {
|
||||
|
||||
// True if this file (or header) was compiled as a C file
|
||||
private predicate isCompiledAsC(File f) {
|
||||
f.compiledAsC()
|
||||
or
|
||||
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
|
||||
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
|
||||
}
|
||||
|
||||
predicate tooManyArguments(FunctionCall fc, Function f) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.8
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @tags reliability
|
||||
* security
|
||||
* external/cwe/cwe-190
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 8.8
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/suspicious-add-sizeof
|
||||
* @tags security
|
||||
* external/cwe/cwe-468
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
|
||||
13
cpp/ql/src/change-notes/released/1.6.0.md
Normal file
13
cpp/ql/src/change-notes/released/1.6.0.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## 1.6.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
|
||||
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
|
||||
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
|
||||
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
|
||||
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
|
||||
10
cpp/ql/src/change-notes/released/1.6.1.md
Normal file
10
cpp/ql/src/change-notes/released/1.6.1.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 1.6.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
|
||||
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
|
||||
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.15
|
||||
lastReleaseVersion: 1.6.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.16-dev
|
||||
version: 1.6.2-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| conftest.c.c:4:3:4:8 | call to strlen | This expression has no effect (because $@ has no external side effects). | conftest.h:3:8:3:13 | strlen | strlen |
|
||||
| conftest_abc.c:4:3:4:8 | call to strlen | This expression has no effect (because $@ has no external side effects). | conftest.h:3:8:3:13 | strlen | strlen |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Likely Typos/ExprHasNoEffect.ql
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "conftest.h"
|
||||
|
||||
int main2() {
|
||||
strlen(""); // GOOD: conftest files are ignored
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "conftest.h"
|
||||
|
||||
int main3() {
|
||||
strlen(""); // BAD: not a `conftest` file, as `conftest` is not directly followed by the extension or a sequence of numbers.
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "conftest.h"
|
||||
|
||||
int main4() {
|
||||
strlen(""); // GOOD: conftest files are ignored
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
typedef long long size_t;
|
||||
|
||||
size_t strlen(const char *s);
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "conftest.h"
|
||||
|
||||
int main5() {
|
||||
strlen(""); // GOOD: conftest files are ignored
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "conftest.h"
|
||||
|
||||
int main1() {
|
||||
strlen(""); // BAD: not a `conftest` file, as `conftest` is not directly followed by the extension or a sequence of numbers.
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.7.65
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.64
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.63
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.64
|
||||
|
||||
No user-facing changes.
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.65
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.63
|
||||
lastReleaseVersion: 1.7.65
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.64-dev
|
||||
version: 1.7.66-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.7.65
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.64
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.63
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -13,11 +13,13 @@ import csharp
|
||||
import Solorigate
|
||||
import experimental.code.csharp.Cryptography.NonCryptographicHashes
|
||||
|
||||
ControlFlowNode loopExitNode(LoopStmt loop) { result.isAfter(loop) }
|
||||
|
||||
from Variable v, Literal l, LoopStmt loop, Expr additional_xor
|
||||
where
|
||||
maybeUsedInFnvFunction(v, _, _, loop) and
|
||||
exists(BitwiseXorOperation xor2 | xor2.getAnOperand() = l and additional_xor = xor2 |
|
||||
loop.getAControlFlowExitNode().getASuccessor*() = xor2.getAControlFlowNode() and
|
||||
loopExitNode(loop).getASuccessor*() = xor2.getControlFlowNode() and
|
||||
xor2.getAnOperand() = v.getAnAccess()
|
||||
)
|
||||
select l, "This literal is used in an $@ after an FNV-like hash calculation with variable $@.",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.64
|
||||
|
||||
No user-facing changes.
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.65
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.63
|
||||
lastReleaseVersion: 1.7.65
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.64-dev
|
||||
version: 1.7.66-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.internal.Completion
|
||||
import ControlFlow
|
||||
import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl::Consistency
|
||||
import semmle.code.csharp.controlflow.internal.Splitting
|
||||
import ControlFlow::Consistency
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import csharp
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
@@ -7,20 +6,6 @@ private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
private module Input implements InputSig<Location, CsharpDataFlow> {
|
||||
private import CsharpDataFlow
|
||||
|
||||
private predicate isStaticAssignable(Assignable a) { a.(Modifiable).isStatic() }
|
||||
|
||||
predicate uniqueEnclosingCallableExclude(Node node) {
|
||||
// TODO: Remove once static initializers are folded into the
|
||||
// static constructors
|
||||
isStaticAssignable(ControlFlowGraphImpl::getNodeCfgScope(node.getControlFlowNode()))
|
||||
}
|
||||
|
||||
predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
|
||||
// TODO: Remove once static initializers are folded into the
|
||||
// static constructors
|
||||
isStaticAssignable(ControlFlowGraphImpl::getNodeCfgScope(call.getControlFlowNode()))
|
||||
}
|
||||
|
||||
predicate uniqueNodeLocationExclude(Node n) {
|
||||
// Methods with multiple implementations
|
||||
n instanceof ParameterNode
|
||||
@@ -70,17 +55,14 @@ private module Input implements InputSig<Location, CsharpDataFlow> {
|
||||
init.getInitializer().getNumberOfChildren() > 1
|
||||
)
|
||||
or
|
||||
exists(ControlFlow::Nodes::ElementNode cfn, ControlFlow::Nodes::Split split |
|
||||
exists(arg.asExprAtNode(cfn))
|
||||
|
|
||||
split = cfn.getASplit() and
|
||||
not split = call.getControlFlowNode().getASplit()
|
||||
or
|
||||
split = call.getControlFlowNode().getASplit() and
|
||||
not split = cfn.getASplit()
|
||||
)
|
||||
or
|
||||
call.(NonDelegateDataFlowCall).getDispatchCall().isReflection()
|
||||
or
|
||||
// Exclude calls that are both getter and setter calls, as they share the same argument nodes.
|
||||
exists(AccessorCall ac |
|
||||
call.(NonDelegateDataFlowCall).getDispatchCall().getCall() = ac and
|
||||
ac instanceof AssignableRead and
|
||||
ac instanceof AssignableWrite
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowPrivate::VariableCapture::Flow::ConsistencyChecks
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate::VariableCapture::Flow::ConsistencyChecks as ConsistencyChecks
|
||||
private import semmle.code.csharp.controlflow.BasicBlocks
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
|
||||
|
||||
query predicate uniqueEnclosingCallable(BasicBlock bb, string msg) {
|
||||
ConsistencyChecks::uniqueEnclosingCallable(bb, msg) and
|
||||
getNodeCfgScope(bb.getFirstNode()) instanceof Callable
|
||||
}
|
||||
|
||||
query predicate consistencyOverview(string msg, int n) { none() }
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
import csharp
|
||||
|
||||
from IntegerLiteral literal
|
||||
where literal.getValue().toInt() = 0
|
||||
where literal.getIntValue() = 0
|
||||
select literal
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
## 5.5.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The predicates `get[L|R]Value` in the class `Assignment` have been deprecated. Use `get[Left|Right]Operand` instead.
|
||||
|
||||
## 5.4.12
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The extractor no longer synthesizes expanded forms of compound assignments. This may have a small impact on the results of queries that explicitly or implicitly rely on the expanded form of compound assignments.
|
||||
* The `cs/log-forging` query no longer treats arguments to extension methods with
|
||||
source code on `ILogger` types as sinks. Instead, taint is tracked interprocedurally
|
||||
through extension method bodies, reducing false positives when extension methods
|
||||
sanitize input internally.
|
||||
|
||||
## 5.4.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -77,7 +77,7 @@ predicate missedAllOpportunity(ForeachStmtGenericEnumerable fes) {
|
||||
// The then case of the if assigns false to something and breaks out of the loop.
|
||||
exists(Assignment a, BoolLiteral bl |
|
||||
a = is.getThen().getAChild*() and
|
||||
bl = a.getRValue() and
|
||||
bl = a.getRightOperand() and
|
||||
bl.toString() = "false"
|
||||
) and
|
||||
is.getThen().getAChild*() instanceof BreakStmt
|
||||
@@ -121,15 +121,17 @@ predicate missedOfTypeOpportunity(ForeachStmtEnumerable fes, LocalVariableDeclSt
|
||||
/**
|
||||
* Holds if `foreach` statement `fes` can be converted to a `.Select()` call.
|
||||
* That is, the loop variable is accessed only in the first statement of the
|
||||
* block, the access is not a cast, and the first statement is a
|
||||
* local variable declaration statement `s`.
|
||||
* block, the access is not a cast, the first statement is a
|
||||
* local variable declaration statement `s`, and the initializer does not
|
||||
* contain an `await` expression (since `Select` does not support async lambdas).
|
||||
*/
|
||||
predicate missedSelectOpportunity(ForeachStmtGenericEnumerable fes, LocalVariableDeclStmt s) {
|
||||
s = firstStmt(fes) and
|
||||
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
|
||||
va = s.getAVariableDeclExpr().getAChildExpr*()
|
||||
) and
|
||||
not s.getAVariableDeclExpr().getInitializer() instanceof Cast
|
||||
not s.getAVariableDeclExpr().getInitializer() instanceof Cast and
|
||||
not s.getAVariableDeclExpr().getInitializer().getAChildExpr*() instanceof AwaitExpr
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C#](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-csharp/).
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The extractor no longer synthesizes expanded forms of compound assignments. This may have a small impact on the results of queries that explicitly or implicitly rely on the expanded form of compound assignments.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Expanded ASP and ASP.NET remote source modeling to cover additional sources, including fields of tainted parameters as well as properties and fields that become tainted transitively.
|
||||
20
csharp/ql/lib/change-notes/2026-04-13-cfg.md
Normal file
20
csharp/ql/lib/change-notes/2026-04-13-cfg.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The C# control flow graph (CFG) implementation has been completely
|
||||
rewritten. The CFG now includes additional nodes to more accurately represent
|
||||
certain constructs. This also means that any existing code that implicitly
|
||||
relies on very specific details about the CFG may need to be updated.
|
||||
The CFG no longer uses splitting, which means that AST nodes now have a unique
|
||||
CFG node representation.
|
||||
Additionally, the following breaking changes have been made:
|
||||
- `ControlFlow::Node` has been renamed to `ControlFlowNode`.
|
||||
- `ControlFlow::Nodes` has been renamed to `ControlFlowNodes`.
|
||||
- `BasicBlock.getCallable` has been renamed to `BasicBlock.getEnclosingCallable`.
|
||||
- `BasicBlocks.qll` has been deleted.
|
||||
- `ControlFlowNode.getAstNode` has changed its meaning. The AST-to-CFG
|
||||
mapping remains one-to-many, but now for a different reason. It used to be
|
||||
because of splitting, but now it's because of additional "helper" CFG
|
||||
nodes. To get the (now canonical) CFG node for a given AST node, use
|
||||
`ControlFlowNode.asExpr()` or `ControlFlowNode.asStmt()` or
|
||||
`ControlFlowElement.getControlFlowNode()` instead.
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 5.4.12
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The extractor no longer synthesizes expanded forms of compound assignments. This may have a small impact on the results of queries that explicitly or implicitly rely on the expanded form of compound assignments.
|
||||
* The `cs/log-forging` query no longer treats arguments to extension methods with
|
||||
source code on `ILogger` types as sinks. Instead, taint is tracked interprocedurally
|
||||
through extension method bodies, reducing false positives when extension methods
|
||||
5
csharp/ql/lib/change-notes/released/5.5.0.md
Normal file
5
csharp/ql/lib/change-notes/released/5.5.0.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 5.5.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The predicates `get[L|R]Value` in the class `Assignment` have been deprecated. Use `get[Left|Right]Operand` instead.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.4.11
|
||||
lastReleaseVersion: 5.5.0
|
||||
|
||||
@@ -96,7 +96,7 @@ private class MethodUse extends Use, QualifiableExpr {
|
||||
private class AccessUse extends Access, Use {
|
||||
AccessUse() {
|
||||
not this.getTarget().(Parameter).getCallable() instanceof Accessor and
|
||||
not this = any(LocalVariableDeclAndInitExpr d).getLValue() and
|
||||
not this = any(LocalVariableDeclAndInitExpr d).getLeftOperand() and
|
||||
not this.isImplicit() and
|
||||
not this instanceof MethodAccess and // handled by `MethodUse`
|
||||
not this instanceof TypeAccess and // handled by `TypeMentionUse`
|
||||
|
||||
@@ -30,7 +30,7 @@ predicate maybeUsedInFnvFunction(Variable v, Operation xor, Operation mul, LoopS
|
||||
e2.getAChild*() = v.getAnAccess() and
|
||||
e1 = xor.getAnOperand() and
|
||||
e2 = mul.getAnOperand() and
|
||||
xor.getAControlFlowNode().getASuccessor*() = mul.getAControlFlowNode() and
|
||||
xor.getControlFlowNode().getASuccessor*() = mul.getControlFlowNode() and
|
||||
(xor instanceof AssignXorExpr or xor instanceof BitwiseXorExpr) and
|
||||
(mul instanceof AssignMulExpr or mul instanceof MulExpr)
|
||||
) and
|
||||
@@ -55,11 +55,11 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
v = addAssign.getTargetVariable() and
|
||||
addAssign.getAChild*() = add and
|
||||
(xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and
|
||||
addAssign.getAControlFlowNode().getASuccessor*() = xor.getAControlFlowNode() and
|
||||
addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and
|
||||
xorAssign.getAChild*() = xor and
|
||||
v = xorAssign.getTargetVariable() and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and
|
||||
xor.getAControlFlowNode().getASuccessor*() = notOp.getAControlFlowNode() and
|
||||
xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and
|
||||
notAssign.getAChild*() = notOp and
|
||||
v = notAssign.getTargetVariable() and
|
||||
loop.getAChild*() = add.getEnclosingStmt() and
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @tags ide-contextual-queries/print-cfg
|
||||
*/
|
||||
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
|
||||
import csharp
|
||||
|
||||
external string selectedSourceFile();
|
||||
|
||||
@@ -21,7 +21,7 @@ external int selectedSourceColumn();
|
||||
|
||||
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
|
||||
|
||||
module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
|
||||
module ViewCfgQueryInput implements ControlFlow::ViewCfgQueryInputSig<File> {
|
||||
predicate selectedSourceFile = selectedSourceFileAlias/0;
|
||||
|
||||
predicate selectedSourceLine = selectedSourceLineAlias/0;
|
||||
@@ -29,7 +29,7 @@ module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
|
||||
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
|
||||
|
||||
predicate cfgScopeSpan(
|
||||
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
|
||||
Callable scope, File file, int startLine, int startColumn, int endLine, int endColumn
|
||||
) {
|
||||
file = scope.getFile() and
|
||||
scope.getLocation().getStartLine() = startLine and
|
||||
@@ -40,11 +40,20 @@ module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
|
||||
|
|
||||
loc = scope.(Callable).getBody().getLocation()
|
||||
or
|
||||
loc = scope.(Field).getInitializer().getLocation()
|
||||
loc = any(AssignExpr init | scope.(ObjectInitMethod).initializes(init)).getLocation()
|
||||
or
|
||||
loc = scope.(Property).getInitializer().getLocation()
|
||||
exists(AssignableMember a, Constructor ctor |
|
||||
scope = ctor and
|
||||
ctor.isStatic() and
|
||||
a.isStatic() and
|
||||
a.getDeclaringType() = ctor.getDeclaringType()
|
||||
|
|
||||
loc = a.(Field).getInitializer().getLocation()
|
||||
or
|
||||
loc = a.(Property).getInitializer().getLocation()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import ViewCfgQuery<File, ViewCfgQueryInput>
|
||||
import ControlFlow::ViewCfgQuery<File, ViewCfgQueryInput>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 5.4.12-dev
|
||||
version: 5.5.1-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -85,8 +85,8 @@ class AssignableRead extends AssignableAccess {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private ControlFlow::Node getAnAdjacentReadSameVar() {
|
||||
SsaImpl::adjacentReadPairSameVar(_, this.getAControlFlowNode(), result)
|
||||
private ControlFlowNode getAnAdjacentReadSameVar() {
|
||||
SsaImpl::adjacentReadPairSameVar(_, this.getControlFlowNode(), result)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,11 +114,7 @@ class AssignableRead extends AssignableAccess {
|
||||
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
AssignableRead getANextRead() {
|
||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||
cfn = this.getAnAdjacentReadSameVar()
|
||||
)
|
||||
}
|
||||
AssignableRead getANextRead() { result.getControlFlowNode() = this.getAnAdjacentReadSameVar() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,7 +231,7 @@ private class RefArg extends AssignableAccess {
|
||||
module AssignableInternal {
|
||||
private predicate tupleAssignmentDefinition(AssignExpr ae, Expr leaf) {
|
||||
exists(TupleExpr te |
|
||||
ae.getLValue() = te and
|
||||
ae.getLeftOperand() = te and
|
||||
te.getAnArgument+() = leaf and
|
||||
// `leaf` is either an assignable access or a local variable declaration
|
||||
not leaf instanceof TupleExpr
|
||||
@@ -249,8 +245,8 @@ module AssignableInternal {
|
||||
*/
|
||||
private predicate tupleAssignmentPair(AssignExpr ae, Expr left, Expr right) {
|
||||
tupleAssignmentDefinition(ae, _) and
|
||||
left = ae.getLValue() and
|
||||
right = ae.getRValue()
|
||||
left = ae.getLeftOperand() and
|
||||
right = ae.getRightOperand()
|
||||
or
|
||||
exists(TupleExpr l, TupleExpr r, int i | tupleAssignmentPair(ae, l, r) |
|
||||
left = l.getArgument(i) and
|
||||
@@ -291,7 +287,7 @@ module AssignableInternal {
|
||||
cached
|
||||
newtype TAssignableDefinition =
|
||||
TAssignmentDefinition(Assignment a) {
|
||||
not a.getLValue() instanceof TupleExpr and
|
||||
not a.getLeftOperand() instanceof TupleExpr and
|
||||
not a instanceof AssignCallOperation and
|
||||
not a instanceof AssignCoalesceExpr
|
||||
} or
|
||||
@@ -358,7 +354,7 @@ module AssignableInternal {
|
||||
// Not defined by dispatch in order to avoid too conservative negative recursion error
|
||||
cached
|
||||
AssignableAccess getTargetAccess(AssignableDefinition def) {
|
||||
def = TAssignmentDefinition(any(Assignment a | a.getLValue() = result))
|
||||
def = TAssignmentDefinition(any(Assignment a | a.getLeftOperand() = result))
|
||||
or
|
||||
def = TTupleAssignmentDefinition(_, result)
|
||||
or
|
||||
@@ -381,8 +377,8 @@ module AssignableInternal {
|
||||
tupleAssignmentPair(ae, ac, result)
|
||||
)
|
||||
or
|
||||
exists(Assignment ass | ac = ass.getLValue() |
|
||||
result = ass.getRValue() and
|
||||
exists(Assignment ass | ac = ass.getLeftOperand() |
|
||||
result = ass.getRightOperand() and
|
||||
not ass instanceof AssignOperation
|
||||
)
|
||||
or
|
||||
@@ -410,7 +406,7 @@ private import AssignableInternal
|
||||
*/
|
||||
class AssignableDefinition extends TAssignableDefinition {
|
||||
/**
|
||||
* DEPRECATED: Use `this.getExpr().getAControlFlowNode()` instead.
|
||||
* DEPRECATED: Use `this.getExpr().getControlFlowNode()` instead.
|
||||
*
|
||||
* Gets a control flow node that updates the targeted assignable when
|
||||
* reached.
|
||||
@@ -419,9 +415,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
* the definitions of `x` and `y` in `M(out x, out y)` and `(x, y) = (0, 1)`
|
||||
* relate to the same call to `M` and assignment node, respectively.
|
||||
*/
|
||||
deprecated ControlFlow::Node getAControlFlowNode() {
|
||||
result = this.getExpr().getAControlFlowNode()
|
||||
}
|
||||
deprecated ControlFlowNode getAControlFlowNode() { result = this.getExpr().getControlFlowNode() }
|
||||
|
||||
/**
|
||||
* Gets the underlying expression that updates the targeted assignable when
|
||||
@@ -494,7 +488,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
AssignableRead getAFirstRead() {
|
||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||
exists(ControlFlowNode cfn | cfn = result.getControlFlowNode() |
|
||||
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
|
||||
this = def.getADefinition()
|
||||
)
|
||||
@@ -527,7 +521,7 @@ module AssignableDefinitions {
|
||||
Assignment getAssignment() { result = a }
|
||||
|
||||
override Expr getSource() {
|
||||
result = a.getRValue() and
|
||||
result = a.getRightOperand() and
|
||||
not a instanceof AddOrRemoveEventExpr
|
||||
}
|
||||
|
||||
@@ -572,11 +566,9 @@ module AssignableDefinitions {
|
||||
}
|
||||
|
||||
/** Holds if a node in basic block `bb` assigns to `ref` parameter `p` via definition `def`. */
|
||||
private predicate basicBlockRefParamDef(
|
||||
ControlFlow::BasicBlock bb, Parameter p, AssignableDefinition def
|
||||
) {
|
||||
private predicate basicBlockRefParamDef(BasicBlock bb, Parameter p, AssignableDefinition def) {
|
||||
def = any(RefArg arg).getAnAnalyzableRefDef(p) and
|
||||
bb.getANode() = def.getExpr().getAControlFlowNode()
|
||||
bb.getANode() = def.getExpr().getControlFlowNode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -585,7 +577,7 @@ module AssignableDefinitions {
|
||||
* any assignments to `p`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate parameterReachesWithoutDef(Parameter p, ControlFlow::BasicBlock bb) {
|
||||
private predicate parameterReachesWithoutDef(Parameter p, BasicBlock bb) {
|
||||
forall(AssignableDefinition def | basicBlockRefParamDef(bb, p, def) |
|
||||
isUncertainRefCall(def.getTargetAccess())
|
||||
) and
|
||||
@@ -593,9 +585,7 @@ module AssignableDefinitions {
|
||||
any(RefArg arg).isAnalyzable(p) and
|
||||
p.getCallable().getEntryPoint() = bb.getFirstNode()
|
||||
or
|
||||
exists(ControlFlow::BasicBlock mid | parameterReachesWithoutDef(p, mid) |
|
||||
bb = mid.getASuccessor()
|
||||
)
|
||||
exists(BasicBlock mid | parameterReachesWithoutDef(p, mid) | bb = mid.getASuccessor())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -607,7 +597,7 @@ module AssignableDefinitions {
|
||||
cached
|
||||
predicate isUncertainRefCall(RefArg arg) {
|
||||
arg.isPotentialAssignment() and
|
||||
exists(ControlFlow::BasicBlock bb, Parameter p | arg.isAnalyzable(p) |
|
||||
exists(BasicBlock bb, Parameter p | arg.isAnalyzable(p) |
|
||||
parameterReachesWithoutDef(p, bb) and
|
||||
bb.getLastNode() = p.getCallable().getExitPoint()
|
||||
)
|
||||
@@ -688,7 +678,7 @@ module AssignableDefinitions {
|
||||
/** Gets the underlying parameter. */
|
||||
Parameter getParameter() { result = p }
|
||||
|
||||
deprecated override ControlFlow::Node getAControlFlowNode() {
|
||||
deprecated override ControlFlowNode getAControlFlowNode() {
|
||||
result = p.getCallable().getEntryPoint()
|
||||
}
|
||||
|
||||
|
||||
@@ -7,23 +7,6 @@ private import csharp
|
||||
* in the same stage across different files.
|
||||
*/
|
||||
module Stages {
|
||||
cached
|
||||
module ControlFlowStage {
|
||||
private import semmle.code.csharp.controlflow.internal.Splitting
|
||||
|
||||
cached
|
||||
predicate forceCachingInSameStage() { any() }
|
||||
|
||||
cached
|
||||
private predicate forceCachingInSameStageRev() {
|
||||
exists(Split s)
|
||||
or
|
||||
exists(ControlFlow::Node n)
|
||||
or
|
||||
forceCachingInSameStageRev()
|
||||
}
|
||||
}
|
||||
|
||||
cached
|
||||
module GuardsStage {
|
||||
private import semmle.code.csharp.controlflow.Guards
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user