mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge branch 'main' into signature_model_refactor
This commit is contained in:
7
.bazelrc
7
.bazelrc
@@ -30,6 +30,13 @@ common --registry=https://bcr.bazel.build
|
||||
|
||||
common --@rules_dotnet//dotnet/settings:strict_deps=false
|
||||
|
||||
# we only configure a nightly toolchain
|
||||
common --@rules_rust//rust/toolchain/channel=nightly
|
||||
|
||||
# rust does not like the gold linker, while bazel does by default, so let's avoid using it
|
||||
common:linux --linkopt=-fuse-ld=lld
|
||||
common:macos --linkopt=-fuse-ld=lld
|
||||
|
||||
# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed
|
||||
common --incompatible_autoload_externally="+@rules_java,+@rules_shell"
|
||||
|
||||
|
||||
4
.github/copilot-instructions.md
vendored
Normal file
4
.github/copilot-instructions.md
vendored
Normal 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.
|
||||
23
.github/workflows/check-overlay-annotations.yml
vendored
Normal file
23
.github/workflows/check-overlay-annotations.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Check overlay annotations
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- 'rc/*'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- 'rc/*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Check overlay annotations
|
||||
run: python config/add-overlay-annotations.py --check java
|
||||
|
||||
35
.github/workflows/go-tests-other-os.yml
vendored
35
.github/workflows/go-tests-other-os.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: "Go: Run Tests - Other OS"
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/ql/**" # don't run other-os if only ql/ files changed
|
||||
- .github/workflows/go-tests-other-os.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
- MODULE.bazel
|
||||
- .bazelrc
|
||||
- misc/bazel/**
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-mac:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
|
||||
test-win:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
22
.github/workflows/go-tests-rtjo.yml
vendored
22
.github/workflows/go-tests-rtjo.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: "Go: Run RTJO Tests"
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-linux:
|
||||
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
|
||||
name: RTJO Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest-xl
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
with:
|
||||
run-code-checks: true
|
||||
dynamic-join-order-mode: all
|
||||
13
.github/workflows/go-tests.yml
vendored
13
.github/workflows/go-tests.yml
vendored
@@ -1,20 +1,9 @@
|
||||
name: "Go: Run Tests"
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
|
||||
38
MODULE.bazel
38
MODULE.bazel
@@ -15,7 +15,7 @@ local_path_override(
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "0.0.11")
|
||||
bazel_dep(name = "rules_go", version = "0.50.1")
|
||||
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")
|
||||
@@ -28,7 +28,7 @@ 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.17.4")
|
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.58.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)
|
||||
@@ -37,7 +37,11 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
|
||||
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
|
||||
RUST_EDITION = "2024"
|
||||
|
||||
RUST_VERSION = "1.86.0"
|
||||
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo)
|
||||
# a nightly toolchain is required to enable experimental_use_cc_common_link, which we require internally
|
||||
# we prefer to run the same version as internally, even if experimental_use_cc_common_link is not really
|
||||
# required in this repo
|
||||
RUST_VERSION = "nightly/2025-08-01"
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
rust.toolchain(
|
||||
@@ -47,6 +51,29 @@ rust.toolchain(
|
||||
"x86_64-apple-darwin",
|
||||
"aarch64-apple-darwin",
|
||||
],
|
||||
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
|
||||
sha256s = {
|
||||
"2025-08-01/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9bbeaf5d3fc7247d31463a9083aa251c995cc50662c8219e7a2254d76a72a9a4",
|
||||
"2025-08-01/rustc-nightly-x86_64-apple-darwin.tar.xz": "c9ea539a8eff0d5d162701f99f9e1aabe14dd0dfb420d62362817a5d09219de7",
|
||||
"2025-08-01/rustc-nightly-aarch64-apple-darwin.tar.xz": "ae83feebbc39cfd982e4ecc8297731fe79c185173aee138467b334c5404b3773",
|
||||
"2025-08-01/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "9f170c30d802a349be60cf52ec46260802093cb1013ad667fc0d528b7b10152f",
|
||||
"2025-08-01/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "9ae5f3cd8f557c4f6df522597c69d14398cf604cfaed2b83e767c4b77a7eaaf6",
|
||||
"2025-08-01/clippy-nightly-x86_64-apple-darwin.tar.xz": "983cb9ee0b6b968188e04ab2d33743d54764b2681ce565e1b3f2b9135c696a3e",
|
||||
"2025-08-01/clippy-nightly-aarch64-apple-darwin.tar.xz": "ed2219dbc49d088225e1b7c5c4390fa295066e071fddaa2714018f6bb39ddbf0",
|
||||
"2025-08-01/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "911f40ab5cbdd686f40e00965271fe47c4805513a308ed01f30eafb25b448a50",
|
||||
"2025-08-01/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "106463c284e48e4904c717471eeec2be5cc83a9d2cae8d6e948b52438cad2e69",
|
||||
"2025-08-01/cargo-nightly-x86_64-apple-darwin.tar.xz": "6ad35c40efc41a8c531ea43235058347b6902d98a9693bf0aed7fc16d5590cef",
|
||||
"2025-08-01/cargo-nightly-aarch64-apple-darwin.tar.xz": "dd28c365e9d298abc3154c797720ad36a0058f131265c9978b4c8e4e37012c8a",
|
||||
"2025-08-01/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "7b431286e12d6b3834b038f078389a00cac73f351e8c3152b2504a3c06420b3b",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "e342e305d7927cc288d386983b2bc253cfad3776b113386e903d0b302648ef47",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "e44dd3506524d85c37b3a54bcc91d01378fd2c590b2db5c5974d12f05c1b84d1",
|
||||
"2025-08-01/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "0c1b5f46dd81be4a9227b10283a0fcaa39c14fea7e81aea6fd6d9887ff6cdc41",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "423e5fd11406adccbc31b8456ceb7375ce055cdf45e90d2c3babeb2d7f58383f",
|
||||
"2025-08-01/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "3c0ceb46a252647a1d4c7116d9ccae684fa5e42aaf3296419febd2c962c3b41d",
|
||||
"2025-08-01/rust-std-nightly-x86_64-apple-darwin.tar.xz": "3be416003cab10f767390a753d1d16ae4d26c7421c03c98992cf1943e5b0efe8",
|
||||
"2025-08-01/rust-std-nightly-aarch64-apple-darwin.tar.xz": "4046ac0ef951cb056b5028a399124f60999fa37792eab69d008d8d7965f389b4",
|
||||
"2025-08-01/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "191ed9d8603c3a4fe5a7bbbc2feb72049078dae2df3d3b7d5dedf3abbf823e6e",
|
||||
},
|
||||
versions = [RUST_VERSION],
|
||||
)
|
||||
use_repo(rust, "rust_toolchains")
|
||||
@@ -206,6 +233,7 @@ use_repo(
|
||||
"kotlin-compiler-2.1.0-Beta1",
|
||||
"kotlin-compiler-2.1.20-Beta1",
|
||||
"kotlin-compiler-2.2.0-Beta1",
|
||||
"kotlin-compiler-2.2.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.6.0",
|
||||
"kotlin-compiler-embeddable-1.6.20",
|
||||
"kotlin-compiler-embeddable-1.7.0",
|
||||
@@ -218,6 +246,7 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-2.1.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.1.20-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.20-Beta2",
|
||||
"kotlin-stdlib-1.6.0",
|
||||
"kotlin-stdlib-1.6.20",
|
||||
"kotlin-stdlib-1.7.0",
|
||||
@@ -230,10 +259,11 @@ use_repo(
|
||||
"kotlin-stdlib-2.1.0-Beta1",
|
||||
"kotlin-stdlib-2.1.20-Beta1",
|
||||
"kotlin-stdlib-2.2.0-Beta1",
|
||||
"kotlin-stdlib-2.2.20-Beta2",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.24.0")
|
||||
go_sdk.download(version = "1.25.0")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
|
||||
## 0.4.12
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
5
actions/ql/lib/change-notes/released/0.4.13.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.13.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
3
actions/ql/lib/change-notes/released/0.4.14.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.14.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.12
|
||||
lastReleaseVersion: 0.4.14
|
||||
|
||||
@@ -72,7 +72,7 @@ string normalizePath(string path) {
|
||||
then result = path
|
||||
else
|
||||
// foo -> GITHUB_WORKSPACE/foo
|
||||
if path.regexpMatch("^[^/~].*")
|
||||
if path.regexpMatch("^[^$/~].*")
|
||||
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
|
||||
else
|
||||
// ~/foo -> ~/foo
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
private import actions
|
||||
private import codeql.actions.TaintTracking
|
||||
private import codeql.actions.dataflow.ExternalFlow
|
||||
private import codeql.actions.security.ControlChecks
|
||||
import codeql.actions.dataflow.FlowSources
|
||||
import codeql.actions.DataFlow
|
||||
|
||||
@@ -65,6 +66,16 @@ class ArgumentInjectionFromMaDSink extends ArgumentInjectionSink {
|
||||
override string getCommand() { result = "unknown" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event that is relevant for the given node in the context of argument injection.
|
||||
*
|
||||
* This is used to highlight the event in the query results when an alert is raised.
|
||||
*/
|
||||
Event getRelevantEventInPrivilegedContext(DataFlow::Node node) {
|
||||
inPrivilegedContext(node.asExpr(), result) and
|
||||
not exists(ControlCheck check | check.protects(node.asExpr(), result, "argument-injection"))
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate a code script.
|
||||
@@ -88,6 +99,16 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig {
|
||||
run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantEventInPrivilegedContext(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */
|
||||
|
||||
@@ -4,6 +4,7 @@ import codeql.actions.DataFlow
|
||||
import codeql.actions.dataflow.FlowSources
|
||||
import codeql.actions.security.PoisonableSteps
|
||||
import codeql.actions.security.UntrustedCheckoutQuery
|
||||
import codeql.actions.security.ControlChecks
|
||||
|
||||
string unzipRegexp() { result = "(unzip|tar)\\s+.*" }
|
||||
|
||||
@@ -262,8 +263,10 @@ class ArtifactPoisoningSink extends DataFlow::Node {
|
||||
|
||||
ArtifactPoisoningSink() {
|
||||
download.getAFollowingStep() = poisonable and
|
||||
// excluding artifacts downloaded to /tmp
|
||||
// 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
|
||||
(
|
||||
@@ -290,6 +293,16 @@ class ArtifactPoisoningSink extends DataFlow::Node {
|
||||
string getPath() { result = download.getPath() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event that is relevant for the given node in the context of artifact poisoning.
|
||||
*
|
||||
* This is used to highlight the event in the query results when an alert is raised.
|
||||
*/
|
||||
Event getRelevantEventInPrivilegedContext(DataFlow::Node node) {
|
||||
inPrivilegedContext(node.asExpr(), result) and
|
||||
not exists(ControlCheck check | check.protects(node.asExpr(), result, "artifact-poisoning"))
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe artifacts
|
||||
* that is used may lead to artifact poisoning
|
||||
@@ -316,6 +329,16 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig {
|
||||
exists(run.getScript().getAFileReadCommand())
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantEventInPrivilegedContext(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe artifacts that is used in an insecure way. */
|
||||
|
||||
@@ -3,6 +3,8 @@ private import codeql.actions.TaintTracking
|
||||
private import codeql.actions.dataflow.ExternalFlow
|
||||
import codeql.actions.dataflow.FlowSources
|
||||
import codeql.actions.DataFlow
|
||||
import codeql.actions.security.ControlChecks
|
||||
import codeql.actions.security.CachePoisoningQuery
|
||||
|
||||
class CodeInjectionSink extends DataFlow::Node {
|
||||
CodeInjectionSink() {
|
||||
@@ -11,6 +13,46 @@ class CodeInjectionSink extends DataFlow::Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for the sink in CodeInjectionCritical.ql.
|
||||
*/
|
||||
Event getRelevantCriticalEventForSink(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection")) and
|
||||
// exclude cases where the sink is a JS script and the expression uses toJson
|
||||
not exists(UsesStep script |
|
||||
script.getCallee() = "actions/github-script" and
|
||||
script.getArgumentExpr("script") = sink.asExpr() and
|
||||
exists(getAToJsonReferenceExpression(sink.asExpr().(Expression).getExpression(), _))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for the sink in CachePoisoningViaCodeInjection.ql.
|
||||
*/
|
||||
Event getRelevantCachePoisoningEventForSink(DataFlow::Node sink) {
|
||||
exists(LocalJob job |
|
||||
job = sink.asExpr().getEnclosingJob() and
|
||||
job.getATriggerEvent() = result and
|
||||
// job can be triggered by an external user
|
||||
result.isExternallyTriggerable() and
|
||||
// excluding privileged workflows since they can be exploited in easier circumstances
|
||||
// which is covered by `actions/code-injection/critical`
|
||||
not job.isPrivilegedExternallyTriggerable(result) and
|
||||
(
|
||||
// the workflow runs in the context of the default branch
|
||||
runsOnDefaultBranch(result)
|
||||
or
|
||||
// the workflow caller runs in the context of the default branch
|
||||
result.getName() = "workflow_call" and
|
||||
exists(ExternalJob caller |
|
||||
caller.getCallee() = job.getLocation().getFile().getRelativePath() and
|
||||
runsOnDefaultBranch(caller.getATriggerEvent())
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate a code script.
|
||||
@@ -35,6 +77,18 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig {
|
||||
exists(run.getScript().getAFileReadCommand())
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantCriticalEventForSink(sink).getLocation()
|
||||
or
|
||||
result = getRelevantCachePoisoningEventForSink(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */
|
||||
|
||||
@@ -3,11 +3,20 @@ private import codeql.actions.TaintTracking
|
||||
private import codeql.actions.dataflow.ExternalFlow
|
||||
import codeql.actions.dataflow.FlowSources
|
||||
import codeql.actions.DataFlow
|
||||
import codeql.actions.security.ControlChecks
|
||||
|
||||
private class CommandInjectionSink extends DataFlow::Node {
|
||||
CommandInjectionSink() { madSink(this, "command-injection") }
|
||||
}
|
||||
|
||||
/** Get the relevant event for the sink in CommandInjectionCritical.ql. */
|
||||
Event getRelevantEventInPrivilegedContext(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.asExpr(), result, ["command-injection", "code-injection"])
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate a system command.
|
||||
@@ -16,6 +25,16 @@ private module CommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantEventInPrivilegedContext(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */
|
||||
|
||||
@@ -72,6 +72,25 @@ class EnvPathInjectionFromMaDSink extends EnvPathInjectionSink {
|
||||
EnvPathInjectionFromMaDSink() { madSink(this, "envpath-injection") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is "artifact".
|
||||
*/
|
||||
Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.asExpr(), result, ["untrusted-checkout", "artifact-poisoning"])
|
||||
) and
|
||||
sink instanceof EnvPathInjectionFromFileReadSink
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is not "artifact".
|
||||
*/
|
||||
Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection"))
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate an environment variable.
|
||||
@@ -108,6 +127,18 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig {
|
||||
exists(run.getScript().getAFileReadCommand())
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation()
|
||||
or
|
||||
result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate the PATH environment variable. */
|
||||
|
||||
@@ -126,6 +126,32 @@ class EnvVarInjectionFromMaDSink extends EnvVarInjectionSink {
|
||||
EnvVarInjectionFromMaDSink() { madSink(this, "envvar-injection") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is "artifact".
|
||||
*/
|
||||
Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check |
|
||||
check
|
||||
.protects(sink.asExpr(), result,
|
||||
["envvar-injection", "untrusted-checkout", "artifact-poisoning"])
|
||||
) and
|
||||
(
|
||||
sink instanceof EnvVarInjectionFromFileReadSink or
|
||||
madSink(sink, "envvar-injection")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is not "artifact".
|
||||
*/
|
||||
Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) {
|
||||
inPrivilegedContext(sink.asExpr(), result) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.asExpr(), result, ["envvar-injection", "code-injection"])
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for unsafe user input
|
||||
* that is used to construct and evaluate an environment variable.
|
||||
@@ -163,6 +189,18 @@ private module EnvVarInjectionConfig implements DataFlow::ConfigSig {
|
||||
exists(run.getScript().getAFileReadCommand())
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
|
||||
Location getASelectedSinkLocation(DataFlow::Node sink) {
|
||||
result = sink.getLocation()
|
||||
or
|
||||
result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation()
|
||||
or
|
||||
result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.13-dev
|
||||
version: 0.4.15-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Environment Path Injection
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job.
|
||||
|
||||
@@ -12,11 +10,11 @@ echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -36,4 +34,4 @@ If an attacker can manipulate the value being set, such as through artifact down
|
||||
|
||||
## References
|
||||
|
||||
- [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
|
||||
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions).
|
||||
|
||||
@@ -21,18 +21,12 @@ import codeql.actions.security.ControlChecks
|
||||
from EnvPathInjectionFlow::PathNode source, EnvPathInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
EnvPathInjectionFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
(
|
||||
not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, "code-injection")
|
||||
)
|
||||
event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode())
|
||||
or
|
||||
source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, ["untrusted-checkout", "artifact-poisoning"])
|
||||
) and
|
||||
sink.getNode() instanceof EnvPathInjectionFromFileReadSink
|
||||
event = getRelevantArtifactEventInPrivilegedContext(sink.getNode())
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential PATH environment variable injection in $@, which may be controlled by an external user ($@).",
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Environment Path Injection
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job.
|
||||
|
||||
@@ -12,11 +10,11 @@ echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -36,4 +34,4 @@ If an attacker can manipulate the value being set, such as through artifact down
|
||||
|
||||
## References
|
||||
|
||||
- [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
|
||||
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Environment Variable Injection
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable:
|
||||
|
||||
@@ -37,7 +35,7 @@ steps:
|
||||
|
||||
If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
1. **Do not allow untrusted data to influence environment variables**:
|
||||
|
||||
@@ -64,7 +62,7 @@ If an attacker can control the values assigned to environment variables and ther
|
||||
} >> "$GITHUB_ENV"
|
||||
```
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Example of Vulnerability
|
||||
|
||||
@@ -113,5 +111,5 @@ An attacker is be able to run arbitrary code by injecting environment variables
|
||||
|
||||
## References
|
||||
|
||||
- [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
|
||||
- [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation)
|
||||
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions).
|
||||
- Synacktiv: [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation).
|
||||
|
||||
@@ -22,26 +22,15 @@ import codeql.actions.security.ControlChecks
|
||||
from EnvVarInjectionFlow::PathNode source, EnvVarInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
EnvVarInjectionFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
// exclude paths to file read sinks from non-artifact sources
|
||||
(
|
||||
// source is text
|
||||
not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, ["envvar-injection", "code-injection"])
|
||||
)
|
||||
event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode())
|
||||
or
|
||||
// source is an artifact or a file from an untrusted checkout
|
||||
source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
|
||||
not exists(ControlCheck check |
|
||||
check
|
||||
.protects(sink.getNode().asExpr(), event,
|
||||
["envvar-injection", "untrusted-checkout", "artifact-poisoning"])
|
||||
) and
|
||||
(
|
||||
sink.getNode() instanceof EnvVarInjectionFromFileReadSink or
|
||||
madSink(sink.getNode(), "envvar-injection")
|
||||
)
|
||||
event = getRelevantArtifactEventInPrivilegedContext(sink.getNode())
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential environment variable injection in $@, which may be controlled by an external user ($@).",
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Environment Variable Injection
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable:
|
||||
|
||||
@@ -37,7 +35,7 @@ steps:
|
||||
|
||||
If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
1. **Do not allow untrusted data to influence environment variables**:
|
||||
|
||||
@@ -64,7 +62,7 @@ If an attacker can control the values assigned to environment variables and ther
|
||||
} >> "$GITHUB_ENV"
|
||||
```
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Example of Vulnerability
|
||||
|
||||
@@ -113,5 +111,5 @@ An attacker would be able to run arbitrary code by injecting environment variabl
|
||||
|
||||
## References
|
||||
|
||||
- [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
|
||||
- [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation)
|
||||
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions).
|
||||
- Synacktiv: [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation).
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
# Code Injection in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_.
|
||||
|
||||
Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_).
|
||||
|
||||
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
|
||||
@@ -22,15 +22,8 @@ import codeql.actions.security.ControlChecks
|
||||
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
CodeInjectionFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
source.getNode().(RemoteFlowSource).getEventName() = event.getName() and
|
||||
not exists(ControlCheck check | check.protects(sink.getNode().asExpr(), event, "code-injection")) and
|
||||
// exclude cases where the sink is a JS script and the expression uses toJson
|
||||
not exists(UsesStep script |
|
||||
script.getCallee() = "actions/github-script" and
|
||||
script.getArgumentExpr("script") = sink.getNode().asExpr() and
|
||||
exists(getAToJsonReferenceExpression(sink.getNode().asExpr().(Expression).getExpression(), _))
|
||||
)
|
||||
event = getRelevantCriticalEventForSink(sink.getNode()) and
|
||||
source.getNode().(RemoteFlowSource).getEventName() = event.getName()
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential code injection in $@, which may be controlled by an external user ($@).", sink,
|
||||
sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName()
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
# Code Injection in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_.
|
||||
|
||||
Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_).
|
||||
|
||||
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
# Use of Actions with known vulnerabilities
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
The security of the workflow and the repository could be compromised by GitHub Actions workflows that utilize GitHub Actions with known vulnerabilities.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Either remove the component from the workflow or upgrade it to a version that is not vulnerable.
|
||||
|
||||
## References
|
||||
|
||||
- [GitHub Docs: Keeping your actions up to date with Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot)
|
||||
- GitHub Docs: [Keeping your actions up to date with Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot).
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
# Actions Job and Workflow Permissions are not set
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
If a GitHub Actions job or workflow has no explicit permissions set, then the repository permissions are used. Repositories created under organizations inherit the organization permissions. The organizations or repositories created before February 2023 have the default permissions set to read-write. Often these permissions do not adhere to the principle of least privilege and can be reduced to read-only, leaving the `write` permission only to a specific types as `issues: write` or `pull-requests: write`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Add the `permissions` key to the job or the root of workflow (in this case it is applied to all jobs in the workflow that do not have their own `permissions` key) and assign the least privileges required to complete the task:
|
||||
Add the `permissions` key to the job or the root of workflow (in this case it is applied to all jobs in the workflow that do not have their own `permissions` key) and assign the least privileges required to complete the task.
|
||||
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
```yaml
|
||||
name: "My workflow"
|
||||
# No permissions block
|
||||
```
|
||||
|
||||
### Correct Usage
|
||||
|
||||
```yaml
|
||||
name: "My workflow"
|
||||
@@ -27,4 +36,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Assigning permissions to jobs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs)
|
||||
- GitHub Docs: [Assigning permissions to jobs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs).
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Improper Access Control
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Sometimes labels are used to approve GitHub Actions. An authorization check may not be properly implemented, allowing an attacker to mutate the code after it has been reviewed and approved by label.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
When using labels, make sure that the code cannot be modified after it has been reviewed and the label has been set.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -57,4 +55,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Events that trigger workflows](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target)
|
||||
- GitHub Docs: [Events that trigger workflows](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target).
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Excessive Secrets Exposure
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
When the workflow runner cannot determine what secrets are needed to run the workflow, it will pass all the available secrets to the runner including organization and repository secrets. This violates the least privileged principle and increases the impact of a potential vulnerability affecting the workflow.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Only pass those secrets that are needed by the workflow. Avoid using expressions such as `toJSON(secrets)` or dynamically accessed secrets such as `secrets[format('GH_PAT_%s', matrix.env)]` since the workflow will need to receive all secrets to decide at runtime which one needs to be used.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -48,5 +46,5 @@ env:
|
||||
|
||||
## References
|
||||
|
||||
- [Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-encrypted-secrets-in-a-workflow)
|
||||
- [Job uses all secrets](https://github.com/boostsecurityio/poutine/blob/main/docs/content/en/rules/job_all_secrets.md)
|
||||
- GitHub Docs: [Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-encrypted-secrets-in-a-workflow).
|
||||
- poutine: [Job uses all secrets](https://github.com/boostsecurityio/poutine/blob/main/docs/content/en/rules/job_all_secrets.md).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Storage of sensitive information in GitHub Actions artifact
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Sensitive information included in a GitHub Actions artifact can allow an attacker to access the sensitive information if the artifact is published.
|
||||
|
||||
@@ -10,6 +8,8 @@ Only store information that is meant to be publicly available in a GitHub Action
|
||||
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
The following example uses `actions/checkout` to checkout code which stores the GITHUB_TOKEN in the \`.git/config\` file and then stores the contents of the \`.git\` repository into the artifact:
|
||||
|
||||
```yaml
|
||||
@@ -28,6 +28,8 @@ jobs:
|
||||
path: .
|
||||
```
|
||||
|
||||
### Correct Usage
|
||||
|
||||
The issue has been fixed below, where the `actions/upload-artifact` uses a version (v4+) which does not include hidden files or directories into the artifact.
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Unmasked Secret Exposure
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Secrets derived from other secrets are not known to the workflow runner, and therefore are not masked unless explicitly registered.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Avoid defining non-plain secrets. For example, do not define a new secret containing a JSON object and then read properties out of it from the workflow, since these read values will not be masked by the workflow runner.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -34,4 +32,4 @@ Avoid defining non-plain secrets. For example, do not define a new secret contai
|
||||
|
||||
## References
|
||||
|
||||
- [Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-encrypted-secrets-in-a-workflow)
|
||||
- GitHub Docs: [Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-encrypted-secrets-in-a-workflow).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Cache Poisoning in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions cache poisoning is a technique that allows an attacker to inject malicious content into the Action's cache from unprivileged workflow, potentially leading to code execution in privileged workflows.
|
||||
|
||||
@@ -23,7 +21,7 @@ In GitHub Actions, cache scopes are primarily determined by the branch structure
|
||||
|
||||
Due to the above design, if something is cached in the context of the default branch (e.g., `main`), it becomes accessible to any feature branch derived from `main`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
1. Avoid using caching in workflows that handle sensitive operations like releases.
|
||||
2. If caching must be used:
|
||||
@@ -34,7 +32,7 @@ Due to the above design, if something is cached in the context of the default br
|
||||
4. Never run untrusted code in the context of the default branch.
|
||||
5. Sign the cache value cryptographically and verify the signature before usage.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -78,6 +76,6 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/)
|
||||
- [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
|
||||
- [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/)
|
||||
- Adnan Khan's Blog: [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
|
||||
- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
|
||||
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
|
||||
|
||||
@@ -18,30 +18,13 @@ import codeql.actions.security.CachePoisoningQuery
|
||||
import CodeInjectionFlow::PathGraph
|
||||
import codeql.actions.security.ControlChecks
|
||||
|
||||
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, LocalJob job, Event event
|
||||
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
CodeInjectionFlow::flowPath(source, sink) and
|
||||
job = sink.getNode().asExpr().getEnclosingJob() and
|
||||
job.getATriggerEvent() = event and
|
||||
// job can be triggered by an external user
|
||||
event.isExternallyTriggerable() and
|
||||
event = getRelevantCachePoisoningEventForSink(sink.getNode()) and
|
||||
// the checkout is not controlled by an access check
|
||||
not exists(ControlCheck check |
|
||||
check.protects(source.getNode().asExpr(), event, "code-injection")
|
||||
) and
|
||||
// excluding privileged workflows since they can be exploited in easier circumstances
|
||||
// which is covered by `actions/code-injection/critical`
|
||||
not job.isPrivilegedExternallyTriggerable(event) and
|
||||
(
|
||||
// the workflow runs in the context of the default branch
|
||||
runsOnDefaultBranch(event)
|
||||
or
|
||||
// the workflow caller runs in the context of the default branch
|
||||
event.getName() = "workflow_call" and
|
||||
exists(ExternalJob caller |
|
||||
caller.getCallee() = job.getLocation().getFile().getRelativePath() and
|
||||
runsOnDefaultBranch(caller.getATriggerEvent())
|
||||
)
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"Unprivileged code injection in $@, which may lead to cache poisoning ($@).", sink,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Cache Poisoning in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions cache poisoning is a technique that allows an attacker to inject malicious content into the Action's cache from unprivileged workflow, potentially leading to code execution in privileged workflows.
|
||||
|
||||
@@ -23,7 +21,7 @@ In GitHub Actions, cache scopes are primarily determined by the branch structure
|
||||
|
||||
Due to the above design, if something is cached in the context of the default branch (e.g., `main`), it becomes accessible to any feature branch derived from `main`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
1. Avoid using caching in workflows that handle sensitive operations like releases.
|
||||
2. If caching must be used:
|
||||
@@ -34,7 +32,7 @@ Due to the above design, if something is cached in the context of the default br
|
||||
4. Never run untrusted code in the context of the default branch.
|
||||
5. Sign the cache value cryptographically and verify the signature before usage.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -123,6 +121,6 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/)
|
||||
- [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
|
||||
- [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/)
|
||||
- Adnan Khan's Blog: [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
|
||||
- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
|
||||
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Cache Poisoning in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Actions cache poisoning is a technique that allows an attacker to inject malicious content into the Action's cache from unprivileged workflow, potentially leading to code execution in privileged workflows.
|
||||
|
||||
@@ -23,7 +21,7 @@ In GitHub Actions, cache scopes are primarily determined by the branch structure
|
||||
|
||||
Due to the above design, if something is cached in the context of the default branch (e.g., `main`), it becomes accessible to any feature branch derived from `main`.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
1. Avoid using caching in workflows that handle sensitive operations like releases.
|
||||
2. If caching must be used:
|
||||
@@ -34,7 +32,7 @@ Due to the above design, if something is cached in the context of the default br
|
||||
4. Never run untrusted code in the context of the default branch.
|
||||
5. Sign the cache value cryptographically and verify the signature before usage.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -80,6 +78,6 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/)
|
||||
- [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
|
||||
- [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/)
|
||||
- Adnan Khan's Blog: [The Monsters in Your Build Cache – GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
|
||||
- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
|
||||
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
# Untrusted Checkout TOCTOU (Time-of-check to time-of-use)
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Untrusted Checkout is protected by a security check but the checked-out branch can be changed after the check.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Verify that the code has not been modified after the security check. This may be achieved differently depending on the type of check:
|
||||
|
||||
- Deployment Environment Approval: Make sure to use a non-mutable reference to the code to be executed. For example use a `sha` instead of a `ref`.
|
||||
- Label Gates: Make sure to use a non-mutable reference to the code to be executed. For example use a `sha` instead of a `ref`.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage (Deployment Environment Approval)
|
||||
|
||||
@@ -99,4 +97,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [ActionsTOCTOU](https://github.com/AdnaneKhan/ActionsTOCTOU)
|
||||
- [ActionsTOCTOU](https://github.com/AdnaneKhan/ActionsTOCTOU).
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
# Untrusted Checkout TOCTOU (Time-of-check to time-of-use)
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Untrusted Checkout is protected by a security check but the checked-out branch can be changed after the check.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Verify that the code has not been modified after the security check. This may be achieved differently depending on the type of check:
|
||||
|
||||
- Deployment Environment Approval: Make sure to use a non-mutable reference to the code to be executed. For example use a `sha` instead of a `ref`.
|
||||
- Label Gates: Make sure to use a non-mutable reference to the code to be executed. For example use a `sha` instead of a `ref`.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage (Deployment Environment Approval)
|
||||
|
||||
@@ -99,4 +97,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [ActionsTOCTOU](https://github.com/AdnaneKhan/ActionsTOCTOU)
|
||||
- [ActionsTOCTOU](https://github.com/AdnaneKhan/ActionsTOCTOU).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# If Condition Always Evaluates to True
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Workflow Expressions (`${{ ... }}`) used in the `if` condition of jobs or steps must not contain extra characters or spaces. Otherwise, the condition is invariably evaluated to `true`.
|
||||
|
||||
@@ -14,7 +12,7 @@ To avoid the vulnerability where an `if` condition always evaluates to `true`, i
|
||||
2. Avoid multiline or spaced-out conditional expressions that might inadvertently introduce unwanted characters or formatting.
|
||||
3. Test the workflow to ensure the `if` conditions behave as expected under different scenarios.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Correct Usage
|
||||
|
||||
@@ -60,4 +58,4 @@ To avoid the vulnerability where an `if` condition always evaluates to `true`, i
|
||||
|
||||
## References
|
||||
|
||||
- [Expression Always True Github Issue](https://github.com/actions/runner/issues/1173)
|
||||
- GitHub actions/runner Issues: [Expression Always True](https://github.com/actions/runner/issues/1173).
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# If Condition Always Evaluates to True
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
GitHub Workflow Expressions (`${{ ... }}`) used in the `if` condition of jobs or steps must not contain extra characters or spaces. Otherwise, the condition is invariably evaluated to `true`.
|
||||
|
||||
@@ -14,7 +12,7 @@ To avoid the vulnerability where an `if` condition always evaluates to `true`, i
|
||||
2. Avoid multiline or spaced-out conditional expressions that might inadvertently introduce unwanted characters or formatting.
|
||||
3. Test the workflow to ensure the `if` conditions behave as expected under different scenarios.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Correct Usage
|
||||
|
||||
@@ -60,4 +58,4 @@ To avoid the vulnerability where an `if` condition always evaluates to `true`, i
|
||||
|
||||
## References
|
||||
|
||||
- [Expression Always True Github Issue](https://github.com/actions/runner/issues/1173)
|
||||
- GitHub actions/runner Issues: [Expression Always True](https://github.com/actions/runner/issues/1173).
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
# Artifact poisoning
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
The workflow downloads artifacts that may be poisoned by an attacker in previously triggered workflows. If the contents of these artifacts are not correctly extracted, stored and verified, they may lead to repository compromise if untrusted code gets executed in a privileged job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
- Always consider artifacts content as untrusted.
|
||||
- Extract the contents of artifacts to a temporary folder so they cannot override existing files.
|
||||
- Verify the contents of the artifacts downloaded. If an artifact is expected to contain a numeric value, verify it before using it.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -69,4 +67,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
@@ -19,10 +19,7 @@ import codeql.actions.security.ControlChecks
|
||||
from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sink, Event event
|
||||
where
|
||||
ArtifactPoisoningFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, "artifact-poisoning")
|
||||
)
|
||||
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()
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
# Artifact poisoning
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
The workflow downloads artifacts that may be poisoned by an attacker in previously triggered workflows. If the contents of these artifacts are not correctly extracted, stored and verified, they may lead to repository compromise if untrusted code gets executed in a privileged job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
- Always consider artifacts content as untrusted.
|
||||
- Extract the contents of artifacts to a temporary folder so they cannot override existing files.
|
||||
- Verify the contents of the artifacts downloaded. If an artifact is expected to contain a numeric value, verify it before using it.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -69,4 +67,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Unpinned tag for 3rd party Action in workflow
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Using a tag for a 3rd party Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
Pinning an action to a full length commit SHA is currently the only way to use a non-immutable action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -24,4 +22,4 @@ Pinning an action to a full length commit SHA is currently the only way to use a
|
||||
|
||||
## References
|
||||
|
||||
- [Using third-party actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)
|
||||
- GitHub Docs: [Using third-party actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions).
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# Execution of Untrusted Checked-out Code
|
||||
## Overview
|
||||
|
||||
## Description
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
|
||||
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
- Avoid using `pull_request_target` unless necessary.
|
||||
- Employ unprivileged `pull_request` workflows followed by `workflow_run` for privileged operations.
|
||||
@@ -14,7 +12,7 @@ The best practice is to handle the potentially untrusted pull request via the **
|
||||
|
||||
The artifacts downloaded from the first workflow should be considered untrusted and must be verified.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -34,7 +32,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm install # scripts in package.json from PR would be executed here
|
||||
npm build
|
||||
|
||||
- uses: completely/fakeaction@v2
|
||||
@@ -134,4 +132,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# Execution of Untrusted Checked-out Code
|
||||
## Overview
|
||||
|
||||
## Description
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
|
||||
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
- Avoid using `pull_request_target` unless necessary.
|
||||
- Employ unprivileged `pull_request` workflows followed by `workflow_run` for privileged operations.
|
||||
@@ -14,7 +12,7 @@ The best practice is to handle the potentially untrusted pull request via the **
|
||||
|
||||
The artifacts downloaded from the first workflow should be considered untrusted and must be verified.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -34,7 +32,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm install # scripts in package.json from PR would be executed here
|
||||
npm build
|
||||
|
||||
- uses: completely/fakeaction@v2
|
||||
@@ -134,4 +132,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# Execution of Untrusted Checked-out Code
|
||||
## Overview
|
||||
|
||||
## Description
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
|
||||
|
||||
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
- Avoid using `pull_request_target` unless necessary.
|
||||
- Employ unprivileged `pull_request` workflows followed by `workflow_run` for privileged operations.
|
||||
@@ -14,7 +12,7 @@ The best practice is to handle the potentially untrusted pull request via the **
|
||||
|
||||
The artifacts downloaded from the first workflow should be considered untrusted and must be verified.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -34,7 +32,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm install # scripts in package.json from PR would be executed here
|
||||
npm build
|
||||
|
||||
- uses: completely/fakeaction@v2
|
||||
@@ -134,4 +132,4 @@ jobs:
|
||||
|
||||
## References
|
||||
|
||||
- [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
# Unneccesary use of advanced configuration
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
The CodeQL workflow does not use any custom settings and could be simplified by switching to the CodeQL default setup.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
If there is no reason to have a custom configuration switch to the CodeQL default setup.
|
||||
|
||||
## References
|
||||
|
||||
- [GitHub Docs: Configuring Default Setup for a repository](https://docs.github.com/en/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning#configuring-default-setup-for-a-repository)
|
||||
- GitHub Docs: [Configuring Default Setup for a repository](https://docs.github.com/en/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning#configuring-default-setup-for-a-repository).
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.5.md
Normal file
3
actions/ql/src/change-notes/released/0.6.5.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
3
actions/ql/src/change-notes/released/0.6.6.md
Normal file
3
actions/ql/src/change-notes/released/0.6.6.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.4
|
||||
lastReleaseVersion: 0.6.6
|
||||
|
||||
@@ -21,10 +21,7 @@ import codeql.actions.security.ControlChecks
|
||||
from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
CommandInjectionFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, ["command-injection", "code-injection"])
|
||||
)
|
||||
event = getRelevantEventInPrivilegedContext(sink.getNode())
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential command injection in $@, which may be controlled by an external user ($@).", sink,
|
||||
sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName()
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
# Argument Injection in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Passing user-controlled arguments to certain commands in the context of `Run` steps may lead to arbitrary code execution.
|
||||
|
||||
Argument injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing the attacker to make changes to the repository.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
When possible avoid passing user-controlled data to commands which may spawn new processes using some of their arguments.
|
||||
|
||||
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -35,7 +33,7 @@ An attacker may set the body of an Issue comment to `BAR/g;1e whoami;#` and the
|
||||
|
||||
## References
|
||||
|
||||
- [Common Weakness Enumeration: CWE-88](https://cwe.mitre.org/data/definitions/88.html).
|
||||
- [Argument Injection Explained](https://sonarsource.github.io/argument-injection-vectors/explained/)
|
||||
- [Argument Injection Vectors](https://sonarsource.github.io/argument-injection-vectors/)
|
||||
- [GTFOBins](https://gtfobins.github.io/)
|
||||
- Common Weakness Enumeration: [CWE-88](https://cwe.mitre.org/data/definitions/88.html).
|
||||
- [Argument Injection Vectors](https://sonarsource.github.io/argument-injection-vectors/).
|
||||
- Argument Injection Vectors: [Argument Injection Explained](https://sonarsource.github.io/argument-injection-vectors/explained/).
|
||||
- [GTFOBins](https://gtfobins.github.io/).
|
||||
|
||||
@@ -20,10 +20,7 @@ import codeql.actions.security.ControlChecks
|
||||
from ArgumentInjectionFlow::PathNode source, ArgumentInjectionFlow::PathNode sink, Event event
|
||||
where
|
||||
ArgumentInjectionFlow::flowPath(source, sink) and
|
||||
inPrivilegedContext(sink.getNode().asExpr(), event) and
|
||||
not exists(ControlCheck check |
|
||||
check.protects(sink.getNode().asExpr(), event, "argument-injection")
|
||||
)
|
||||
event = getRelevantEventInPrivilegedContext(sink.getNode())
|
||||
select sink.getNode(), source, sink,
|
||||
"Potential argument injection in $@ command, which may be controlled by an external user ($@).",
|
||||
sink, sink.getNode().(ArgumentInjectionSink).getCommand(), event, event.getName()
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
# Argument Injection in GitHub Actions
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
Passing user-controlled arguments to certain commands in the context of `Run` steps may lead to arbitrary code execution.
|
||||
|
||||
Argument injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing the attacker to make changes to the repository.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
When possible avoid passing user-controlled data to commands which may spawn new processes using some of their arguments.
|
||||
|
||||
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -35,7 +33,7 @@ An attacker may set the body of an Issue comment to `BAR|g;1e whoami;#` and the
|
||||
|
||||
## References
|
||||
|
||||
- [Common Weakness Enumeration: CWE-88](https://cwe.mitre.org/data/definitions/88.html).
|
||||
- [Argument Injection Explained](https://sonarsource.github.io/argument-injection-vectors/explained/)
|
||||
- [Argument Injection Vectors](https://sonarsource.github.io/argument-injection-vectors/)
|
||||
- [GTFOBins](https://gtfobins.github.io/)
|
||||
- Common Weakness Enumeration: [CWE-88](https://cwe.mitre.org/data/definitions/88.html).
|
||||
- [Argument Injection Vectors](https://sonarsource.github.io/argument-injection-vectors/).
|
||||
- Argument Injection Vectors: [Argument Injection Explained](https://sonarsource.github.io/argument-injection-vectors/explained/).
|
||||
- [GTFOBins](https://gtfobins.github.io/).
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# Unversioned Immutable Action
|
||||
|
||||
## Description
|
||||
## Overview
|
||||
|
||||
This action is eligible for Immutable Actions, a new GitHub feature that is currently only available for internal users. Immutable Actions are released as packages in the GitHub package registry instead of resolved from a pinned SHA at the repository. The Immutable Action provides the same immutability as pinning the version to a SHA but with improved readability and additional security guarantees.
|
||||
|
||||
## Recommendations
|
||||
## Recommendation
|
||||
|
||||
For internal users: when using [immutable actions](https://github.com/github/package-registry-team/blob/main/docs/immutable-actions/immutable-actions-howto.md) use the full semantic version of the action. This will ensure that the action is resolved to the exact version stored in the GitHub package registry.
|
||||
|
||||
## Examples
|
||||
## Example
|
||||
|
||||
### Incorrect Usage
|
||||
|
||||
@@ -25,4 +23,4 @@ For internal users: when using [immutable actions](https://github.com/github/pac
|
||||
|
||||
## References
|
||||
|
||||
- [Consuming immutable actions]()
|
||||
- [Consuming immutable actions]().
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.5-dev
|
||||
version: 0.6.7-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning93.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning93.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning94.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning94.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: /tmp/artifacts/
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning95.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning95.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: $RUNNER_TEMP/artifacts/
|
||||
- run: npm install
|
||||
18
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning96.yml
vendored
Normal file
18
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning96.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
- run: npm install
|
||||
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning97.yml
vendored
Normal file
19
actions/ql/test/query-tests/Security/CWE-829/.github/workflows/artifactpoisoning97.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
@@ -13,6 +13,7 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .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 | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .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 | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -44,6 +45,8 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | 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 | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
@@ -66,6 +69,7 @@ subpaths
|
||||
| .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 |
|
||||
|
||||
@@ -13,6 +13,7 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .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 | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .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 | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -44,6 +45,8 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | 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 | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
|
||||
@@ -51,6 +51,16 @@ edges
|
||||
| .github/workflows/artifactpoisoning92.yml:19:9:25:6 | Run Step: metadata | .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:9:29:27 | Run Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:12:9:13:6 | Uses Step | .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:9:18:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:19:9:19:25 | Run Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:16:9:19:59 | Run Step: pr_number |
|
||||
| .github/workflows/auto_ci.yml:20:9:27:6 | Uses Step | .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step |
|
||||
| .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step | .github/workflows/auto_ci.yml:32:9:37:6 | Run Step |
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"files": [
|
||||
"cpp/ql/lib/semmlecode.cpp.dbscheme",
|
||||
"javascript/ql/lib/semmlecode.javascript.dbscheme",
|
||||
"python/ql/lib/semmlecode.python.dbscheme",
|
||||
"ruby/ql/lib/ruby.dbscheme",
|
||||
"ql/ql/src/ql.dbscheme"
|
||||
],
|
||||
"fragments": [
|
||||
"/*- Compilations -*/",
|
||||
"/*- External data -*/",
|
||||
"/*- Files and folders -*/",
|
||||
"/*- Diagnostic messages -*/",
|
||||
@@ -21,6 +23,7 @@
|
||||
"/*- DEPRECATED: Snapshot date -*/",
|
||||
"/*- DEPRECATED: Duplicate code -*/",
|
||||
"/*- DEPRECATED: Version control data -*/",
|
||||
"/*- C++ dbscheme -*/",
|
||||
"/*- JavaScript-specific part -*/",
|
||||
"/*- Ruby dbscheme -*/",
|
||||
"/*- Erb dbscheme -*/",
|
||||
|
||||
@@ -231,35 +231,10 @@
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll",
|
||||
"rust/ql/lib/codeql/rust/security/CryptoAlgorithms.qll"
|
||||
],
|
||||
"CryptoAlgorithmNames Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/CryptoAlgorithmNames.qll",
|
||||
"python/ql/lib/semmle/python/concepts/internal/CryptoAlgorithmNames.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/CryptoAlgorithmNames.qll"
|
||||
],
|
||||
"SensitiveDataHeuristics Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
||||
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"IncompleteUrlSubstringSanitization": [
|
||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||
"ruby/ql/src/queries/security/cwe-020/IncompleteUrlSubstringSanitization.qll"
|
||||
],
|
||||
"Concepts Python/Ruby/JS": [
|
||||
"python/ql/lib/semmle/python/internal/ConceptsShared.qll",
|
||||
"ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll",
|
||||
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll",
|
||||
"rust/ql/lib/codeql/rust/internal/ConceptsShared.qll"
|
||||
],
|
||||
"ApiGraphModels": [
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
|
||||
|
||||
@@ -2,6 +2,9 @@ language: cpp
|
||||
strategy: dca
|
||||
destination: cpp/ql/lib/ext/generated
|
||||
targets:
|
||||
- name: glibc
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: zlib
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
|
||||
2423
cpp/downgrades/5340d6d5f428557632b1a50113e406430f29ef7d/old.dbscheme
Normal file
2423
cpp/downgrades/5340d6d5f428557632b1a50113e406430f29ef7d/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Uncomment cases in dbscheme
|
||||
compatibility: full
|
||||
2428
cpp/downgrades/5491582ac8511726e12fae3e2399000f9201cd9a/old.dbscheme
Normal file
2428
cpp/downgrades/5491582ac8511726e12fae3e2399000f9201cd9a/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Remove unused external_package tables from the dbscheme
|
||||
compatibility: full
|
||||
@@ -0,0 +1,9 @@
|
||||
class Function extends @function {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Function f, string n, int k, int new_k
|
||||
where
|
||||
functions(f, n, k) and
|
||||
if builtin_functions(f) then new_k = 6 else new_k = k
|
||||
select f, n, new_k
|
||||
2433
cpp/downgrades/801b2f03360d78c85f51fbad9b75956fa8d58b00/old.dbscheme
Normal file
2433
cpp/downgrades/801b2f03360d78c85f51fbad9b75956fa8d58b00/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Move builtin function identification to its own table
|
||||
compatibility: full
|
||||
functions.rel: run functions.qlo
|
||||
builtin_functions.rel: delete
|
||||
2451
cpp/downgrades/827dbc206ea55377e032a8a934c8903fedc50fa0/old.dbscheme
Normal file
2451
cpp/downgrades/827dbc206ea55377e032a8a934c8903fedc50fa0/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: sync dbscheme and delete svn tables
|
||||
compatibility: full
|
||||
@@ -0,0 +1,161 @@
|
||||
class Accessible extends @accessible {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Container extends @container {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Initialiser extends @initialiser {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_default {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Stmt extends @stmt {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isLocationDefault(Location l) {
|
||||
diagnostics(_, _, _, _, _, l)
|
||||
or
|
||||
macroinvocations(_, _, l, _)
|
||||
or
|
||||
fun_decls(_, _, _, _, l)
|
||||
or
|
||||
var_decls(_, _, _, _, l)
|
||||
or
|
||||
type_decls(_, _, l)
|
||||
or
|
||||
namespace_decls(_, _, l, _)
|
||||
or
|
||||
namespace_decls(_, _, _, l)
|
||||
or
|
||||
usings(_, _, l, _)
|
||||
or
|
||||
static_asserts(_, _, _, l, _)
|
||||
or
|
||||
enumconstants(_, _, _, _, _, l)
|
||||
or
|
||||
concept_templates(_, _, l)
|
||||
or
|
||||
attributes(_, _, _, _, l)
|
||||
or
|
||||
attribute_args(_, _, _, _, l)
|
||||
or
|
||||
derivations(_, _, _, _, l)
|
||||
or
|
||||
frienddecls(_, _, _, l)
|
||||
or
|
||||
comments(_, _, l)
|
||||
or
|
||||
namequalifiers(_, _, _, l)
|
||||
or
|
||||
lambda_capture(_, _, _, _, _, _, l)
|
||||
or
|
||||
preprocdirects(_, _, l)
|
||||
or
|
||||
xmllocations(_, l)
|
||||
or
|
||||
locations_default(l, _, 0, 0, 0, 0) // For containers.
|
||||
}
|
||||
|
||||
predicate isLocationExpr(Location l) {
|
||||
initialisers(_, _, _, l)
|
||||
or
|
||||
exprs(_, _, l)
|
||||
}
|
||||
|
||||
predicate isLocationStmt(Location l) { stmts(_, _, l) }
|
||||
|
||||
newtype TExprOrStmtLocation =
|
||||
TExprLocation(Location l, Container c, int startLine, int startColumn, int endLine, int endColumn) {
|
||||
isLocationExpr(l) and
|
||||
(isLocationDefault(l) or isLocationStmt(l)) and
|
||||
locations_default(l, c, startLine, startColumn, endLine, endColumn)
|
||||
} or
|
||||
TStmtLocation(Location l, Container c, int startLine, int startColumn, int endLine, int endColumn) {
|
||||
isLocationStmt(l) and
|
||||
(isLocationDefault(l) or isLocationExpr(l)) and
|
||||
locations_default(l, c, startLine, startColumn, endLine, endColumn)
|
||||
}
|
||||
|
||||
module Fresh = QlBuiltins::NewEntity<TExprOrStmtLocation>;
|
||||
|
||||
class NewLocationBase = @location_default or Fresh::EntityId;
|
||||
|
||||
class NewLocation extends NewLocationBase {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
query predicate new_locations_default(
|
||||
NewLocation l, Container c, int startLine, int startColumn, int endLine, int endColumn
|
||||
) {
|
||||
isLocationDefault(l) and
|
||||
locations_default(l, c, startLine, startColumn, endLine, endColumn)
|
||||
}
|
||||
|
||||
query predicate new_locations_expr(
|
||||
NewLocation l, Container c, int startLine, int startColumn, int endLine, int endColumn
|
||||
) {
|
||||
exists(Location l_old |
|
||||
isLocationExpr(l_old) and
|
||||
locations_default(l_old, c, startLine, startColumn, endLine, endColumn)
|
||||
|
|
||||
if not isLocationDefault(l_old) and not isLocationStmt(l)
|
||||
then l = l_old
|
||||
else l = Fresh::map(TExprLocation(l_old, c, startLine, startColumn, endLine, endColumn))
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_locations_stmt(
|
||||
NewLocation l, Container c, int startLine, int startColumn, int endLine, int endColumn
|
||||
) {
|
||||
exists(Location l_old |
|
||||
isLocationStmt(l_old) and
|
||||
locations_default(l_old, c, startLine, startColumn, endLine, endColumn)
|
||||
|
|
||||
if not isLocationDefault(l_old) and not isLocationExpr(l)
|
||||
then l = l_old
|
||||
else l = Fresh::map(TStmtLocation(l_old, c, startLine, startColumn, endLine, endColumn))
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_exprs(Expr e, int kind, NewLocation l) {
|
||||
exists(Location l_old, Container c, int startLine, int startColumn, int endLine, int endColumn |
|
||||
exprs(e, kind, l_old) and
|
||||
locations_default(l_old, c, startLine, startColumn, endLine, endColumn)
|
||||
|
|
||||
if not isLocationDefault(l_old) and not isLocationStmt(l)
|
||||
then l = l_old
|
||||
else l = Fresh::map(TExprLocation(l_old, c, startLine, startColumn, endLine, endColumn))
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_initialisers(Initialiser i, Accessible v, Expr e, NewLocation l) {
|
||||
exists(Location l_old, Container c, int startLine, int startColumn, int endLine, int endColumn |
|
||||
initialisers(i, v, e, l_old) and
|
||||
locations_default(l_old, c, startLine, startColumn, endLine, endColumn)
|
||||
|
|
||||
if not isLocationDefault(l_old) and not isLocationStmt(l)
|
||||
then l = l_old
|
||||
else l = Fresh::map(TExprLocation(l_old, c, startLine, startColumn, endLine, endColumn))
|
||||
)
|
||||
}
|
||||
|
||||
query predicate new_stmts(Stmt s, int kind, NewLocation l) {
|
||||
exists(Location l_old, Container c, int startLine, int startColumn, int endLine, int endColumn |
|
||||
stmts(s, kind, l_old) and
|
||||
locations_default(l_old, c, startLine, startColumn, endLine, endColumn)
|
||||
|
|
||||
if not isLocationDefault(l_old) and not isLocationExpr(l)
|
||||
then l = l_old
|
||||
else l = Fresh::map(TStmtLocation(l_old, c, startLine, startColumn, endLine, endColumn))
|
||||
)
|
||||
}
|
||||
2475
cpp/downgrades/e70d0b653187b93d9688f21c9db46bb1cd46ab78/old.dbscheme
Normal file
2475
cpp/downgrades/e70d0b653187b93d9688f21c9db46bb1cd46ab78/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
description: Merge location tables
|
||||
compatibility: partial
|
||||
locations_default.rel: run downgrades.ql new_locations_default
|
||||
locations_expr.rel: run downgrades.ql new_locations_expr
|
||||
locations_stmt.rel: run downgrades.ql new_locations_stmt
|
||||
exprs.rel: run downgrades.ql new_exprs
|
||||
initialisers.rel: run downgrades.ql new_initialisers
|
||||
stmts.rel: run downgrades.ql new_stmts
|
||||
@@ -4,4 +4,3 @@
|
||||
int main() {
|
||||
return ONE + TWO + THREE + FOUR;
|
||||
}
|
||||
// semmle-extractor-options: --clang -include-pch ${testdir}/clang-pch.testproj/a.pch -Iextra_dummy_path
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
|
||||
## 5.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
4
cpp/ql/lib/change-notes/2025-08-02-gvn.md
Normal file
4
cpp/ql/lib/change-notes/2025-08-02-gvn.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The global value numbering library (`semmle.code.cpp.valuenumbering.GlobalValueNumbering` and `semmle.code.cpp.ir.ValueNumbering`) has been improved so more expressions are assigned the same value number.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved dataflow through global variables in the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`). Queries based on these libraries will produce more results on codebases with many global variables.
|
||||
4
cpp/ql/lib/change-notes/2025-08-13-guards.md
Normal file
4
cpp/ql/lib/change-notes/2025-08-13-guards.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The guards libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been improved to recognize more guards.
|
||||
16
cpp/ql/lib/change-notes/released/5.3.0.md
Normal file
16
cpp/ql/lib/change-notes/released/5.3.0.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
9
cpp/ql/lib/change-notes/released/5.4.0.md
Normal file
9
cpp/ql/lib/change-notes/released/5.4.0.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.2.0
|
||||
lastReleaseVersion: 5.4.0
|
||||
|
||||
@@ -8,7 +8,7 @@ module CryptoInput implements InputSig<Language::Location> {
|
||||
|
||||
class LocatableElement = Language::Locatable;
|
||||
|
||||
class UnknownLocation = Language::UnknownDefaultLocation;
|
||||
class UnknownLocation = Language::UnknownLocation;
|
||||
|
||||
LocatableElement dfn_to_element(DataFlow::Node node) {
|
||||
result = node.asExpr() or
|
||||
|
||||
@@ -32,4 +32,18 @@ extensions:
|
||||
- ["", "", False, "CommandLineToArgvA", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
- ["", "", False, "CommandLineToArgvW", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
# fileapi.h
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
# processthreadsapi.h
|
||||
- ["", "", False, "CreateThread", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThread", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
# wdm.h
|
||||
- ["", "", False, "RtlCopyVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyDeviceMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemoryNonTemporal", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyUnicodeString", "", "", "Argument[*1].Field[*Buffer]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user