From 643080208b38f793b75d3d390280f26b57b2f8f3 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 9 Jul 2026 17:01:29 -0400 Subject: [PATCH 1/2] Add UntrustedCheckoutTOCTOUX ControlCheck model fix --- actions/ql/lib/codeql/actions/security/ControlChecks.qll | 4 +--- .../src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql | 3 ++- .../Security/CWE-367/UntrustedCheckoutTOCTOUCritical.expected | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index 41f512abbc34..900f62556b05 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -144,9 +144,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 = any_category() - or - event = actor_not_attacker_event() and category = non_toctou_category() + event = [actor_is_attacker_event(), actor_not_attacker_event()] and category = non_toctou_category() } } diff --git a/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql b/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql index 2aacf20b35fc..14a6c9a4c569 100644 --- a/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql +++ b/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql @@ -23,7 +23,8 @@ where // the checked-out code may lead to arbitrary code execution checkout.getAFollowingStep() = step and // the checkout occurs in a privileged context - inPrivilegedContext(checkout, event) and + inPrivilegedContext(checkout, event) + and // the mutable checkout step is protected by an Insufficient access check exists(ControlCheck check1 | check1.protects(checkout, event, "untrusted-checkout")) and not exists(ControlCheck check2 | check2.protects(checkout, event, "untrusted-checkout-toctou")) diff --git a/actions/ql/test/query-tests/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.expected b/actions/ql/test/query-tests/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.expected index da66ff822a39..4f0bd967c2b0 100644 --- a/actions/ql/test/query-tests/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.expected +++ b/actions/ql/test/query-tests/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.expected @@ -99,6 +99,8 @@ edges #select | .github/workflows/comment.yml:58:9:60:2 | Run Step | .github/workflows/comment.yml:54:9:58:6 | Uses Step | .github/workflows/comment.yml:58:9:60:2 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/comment.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/comment.yml:68:9:68:43 | Run Step | .github/workflows/comment.yml:64:9:68:6 | Uses Step | .github/workflows/comment.yml:68:9:68:43 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/comment.yml:4:3:4:15 | issue_comment | issue_comment | +| .github/workflows/deployment1.yml:27:10:30:7 | Run Step | .github/workflows/deployment1.yml:16:10:22:7 | Uses Step | .github/workflows/deployment1.yml:27:10:30:7 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/deployment1.yml:5:3:5:21 | pull_request_target | pull_request_target | +| .github/workflows/deployment1.yml:30:10:31:53 | Run Step | .github/workflows/deployment1.yml:16:10:22:7 | Uses Step | .github/workflows/deployment1.yml:30:10:31:53 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/deployment1.yml:5:3:5:21 | pull_request_target | pull_request_target | | .github/workflows/test0.yml:58:9:60:2 | Run Step | .github/workflows/test0.yml:54:9:58:6 | Uses Step | .github/workflows/test0.yml:58:9:60:2 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/test0.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/test0.yml:68:9:68:43 | Run Step | .github/workflows/test0.yml:64:9:68:6 | Uses Step | .github/workflows/test0.yml:68:9:68:43 | Run Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/test0.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/test4.yml:85:7:88:54 | Uses Step | .github/workflows/test4.yml:79:7:85:4 | Uses Step | .github/workflows/test4.yml:85:7:88:54 | Uses Step | Insufficient protection against execution of untrusted code on a privileged workflow ($@). | .github/workflows/test4.yml:5:3:5:15 | issue_comment | issue_comment | From 059aa2da70a139c61b6eac5bfcd37645186ea767 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 10 Jul 2026 00:04:33 -0400 Subject: [PATCH 2/2] Add missing changenote --- .../change-notes/2026-07-09-environment-check-alteration.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 actions/ql/lib/change-notes/2026-07-09-environment-check-alteration.md diff --git a/actions/ql/lib/change-notes/2026-07-09-environment-check-alteration.md b/actions/ql/lib/change-notes/2026-07-09-environment-check-alteration.md new file mode 100644 index 000000000000..e7b49abddf71 --- /dev/null +++ b/actions/ql/lib/change-notes/2026-07-09-environment-check-alteration.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Altered the logic of `EnvironmentCheck` to make sure it is a check that protects only for non-toctou. This change will result in more results being found by the queries: `actions/untrusted-checkout-toctou/high` and `actions/untrusted-checkout-toctou/critical`. \ No newline at end of file