From 436be5c20bdd0790c170c70815e8bcd431f6f6c9 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 10 Jul 2026 19:36:53 -0400 Subject: [PATCH 1/2] Add implementation for technique to customize environmentCheck in actions queries --- actions/ql/lib/actions.qll | 2 ++ actions/ql/lib/codeql/actions/config/Config.qll | 16 ++++++++++++++++ .../codeql/actions/config/ConfigExtensions.qll | 12 ++++++++++++ .../codeql/actions/security/ControlChecks.qll | 14 +++++++++++++- actions/ql/lib/ext/config/customize_checks.yml | 9 +++++++++ .../ql/lib/ext/config/deployment_environment.yml | 6 ++++++ 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 actions/ql/lib/ext/config/customize_checks.yml create mode 100644 actions/ql/lib/ext/config/deployment_environment.yml diff --git a/actions/ql/lib/actions.qll b/actions/ql/lib/actions.qll index 2c1d1cee9259..a1ee60b1694d 100644 --- a/actions/ql/lib/actions.qll +++ b/actions/ql/lib/actions.qll @@ -1 +1,3 @@ import codeql.actions.Ast + +abstract class CustomEnvEnable extends Environment { } diff --git a/actions/ql/lib/codeql/actions/config/Config.qll b/actions/ql/lib/codeql/actions/config/Config.qll index e6359c142582..72f1b7614594 100644 --- a/actions/ql/lib/codeql/actions/config/Config.qll +++ b/actions/ql/lib/codeql/actions/config/Config.qll @@ -164,3 +164,19 @@ predicate untrustedGhCommandDataModel(string cmd_regex, string flag) { predicate actionsPermissionsDataModel(string action, string permission) { Extensions::actionsPermissionsDataModel(action, permission) } + +/** + * MaD models for deployment environments + * Fields: + * - name: deployment environment name, e.g. `Public CI` + */ +predicate enabledDeploymentEnvironmentDataModel(string name) { + Extensions::enabledDeploymentEnvironmentDataModel(name) +} + +/** + * `EnvironmentCheck` implementation model. + */ +predicate selectDeploymentEnvironmentDataModel(string selected) { + Extensions::selectDeploymentEnvironmentDataModel(selected) +} diff --git a/actions/ql/lib/codeql/actions/config/ConfigExtensions.qll b/actions/ql/lib/codeql/actions/config/ConfigExtensions.qll index 87a919359404..e0ca6a4da340 100644 --- a/actions/ql/lib/codeql/actions/config/ConfigExtensions.qll +++ b/actions/ql/lib/codeql/actions/config/ConfigExtensions.qll @@ -88,3 +88,15 @@ extensible predicate untrustedGhCommandDataModel(string cmd_regex, string flag); * - see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token for documentation of token permissions. */ extensible predicate actionsPermissionsDataModel(string action, string permission); + +/** + * Holds for deployment environments that exist for a given repository. + * Requires this to be externally supplied but once done can be used to + * toggle precision of whether that suffices or not as a control check. + */ +extensible predicate enabledDeploymentEnvironmentDataModel(string name); + +/** + * Selects which deployment environments model to use to implement `EnvironmentCheck`. + */ +extensible predicate selectDeploymentEnvironmentDataModel(string mechanism); diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index 4d3dbc38c657..e95b2271f811 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -277,10 +277,22 @@ abstract class LabelCheck extends ControlCheck { } class EnvironmentCheck extends ControlCheck instanceof Environment { + EnvironmentCheck() { + exists(string selected | + selectDeploymentEnvironmentDataModel(selected) and + if selected = "EnvironmentCheckMaD" + then enabledDeploymentEnvironmentDataModel(this.(Environment).getName()) + else + if selected = "EnvironmentCheckCustomQL" + then this instanceof CustomEnvEnable + else this instanceof Environment + ) + } + // Environment checks are not effective against any mutable attacks // they do actually protect against untrusted code execution (sha) override predicate protectsCategoryAndEvent(string category, string event) { - event = actor_is_attacker_event() and category = any_category() + event = actor_is_attacker_event() and category = toctou_category() or event = actor_not_attacker_event() and category = non_toctou_category() } diff --git a/actions/ql/lib/ext/config/customize_checks.yml b/actions/ql/lib/ext/config/customize_checks.yml new file mode 100644 index 000000000000..c630d8be80c7 --- /dev/null +++ b/actions/ql/lib/ext/config/customize_checks.yml @@ -0,0 +1,9 @@ +extensions: + - addsTo: + pack: codeql/actions-all + extensible: selectDeploymentEnvironmentDataModel + data: + # The possible values this can take are: + # EnvironmentCheckCustomQL - for a custom QL implementation for the sufficient EnvironmentCheck. + # EnvironmentCheckMaD - for a custom MaD list of deployment environments that are relevant to a database. + - [""] \ No newline at end of file diff --git a/actions/ql/lib/ext/config/deployment_environment.yml b/actions/ql/lib/ext/config/deployment_environment.yml new file mode 100644 index 000000000000..6517614139e0 --- /dev/null +++ b/actions/ql/lib/ext/config/deployment_environment.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/actions-all + extensible: enabledDeploymentEnvironmentDataModel + data: + - [""] \ No newline at end of file From cdffef8684c2f2608eee4f691b536a7882310468 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 10 Jul 2026 19:58:23 -0400 Subject: [PATCH 2/2] Fix accidental change in ControlChecks.qll --- actions/ql/lib/codeql/actions/security/ControlChecks.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index e95b2271f811..4a68d50549dc 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -292,7 +292,7 @@ class EnvironmentCheck extends ControlCheck instanceof Environment { // Environment checks are not effective against any mutable attacks // they do actually protect against untrusted code execution (sha) override predicate protectsCategoryAndEvent(string category, string event) { - event = actor_is_attacker_event() and category = toctou_category() + event = actor_is_attacker_event() and category = any_category() or event = actor_not_attacker_event() and category = non_toctou_category() }