From 2eed6c1736a87640d7d93d6d8a473b7372cd4212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Loba=C4=8Devski?= Date: Mon, 15 Jun 2026 05:42:59 +0000 Subject: [PATCH 1/3] Fix dominates() false positive in reusable workflows --- .../2026-06-15-permission_check.md | 4 +++ .../codeql/actions/security/ControlChecks.qll | 23 ++++++++++++++ .../TestRepo/.github/workflows/build.yml | 17 ++++++++++ .../workflows/untrusted_checkout_no_needs.yml | 31 +++++++++++++++++++ ...ted_checkout_permission_check_reusable.yml | 26 ++++++++++++++++ .../untrusted_checkout_permissions_check.yml | 31 +++++++++++++++++++ .../UntrustedCheckoutCritical.expected | 7 +++++ 7 files changed, 139 insertions(+) create mode 100644 actions/ql/lib/change-notes/2026-06-15-permission_check.md create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_no_needs.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permissions_check.yml diff --git a/actions/ql/lib/change-notes/2026-06-15-permission_check.md b/actions/ql/lib/change-notes/2026-06-15-permission_check.md new file mode 100644 index 000000000000..b3b8f5faf00c --- /dev/null +++ b/actions/ql/lib/change-notes/2026-06-15-permission_check.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* GitHub Actions support for reusable workflows was improved. \ No newline at end of file diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index 41f512abbc34..bf289b85f2d2 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -85,6 +85,29 @@ abstract class ControlCheck extends AstNode { or node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this.(Step) ) + or + // When the node is inside a reusable workflow, check if the control check + // dominates the caller job in the calling workflow. + exists(ExternalJob caller | + caller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and + ( + this instanceof If and + ( + caller.getIf() = this or + caller.getANeededJob().(LocalJob).getIf() = this or + caller.getANeededJob().(LocalJob).getAStep().getIf() = this + ) + or + this instanceof Environment and + ( + caller.getEnvironment() = this or + caller.getANeededJob().getEnvironment() = this + ) + or + (this instanceof Run or this instanceof UsesStep) and + caller.getANeededJob().(LocalJob).getAStep() = this.(Step) + ) + ) } abstract predicate protectsCategoryAndEvent(string category, string event); diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml new file mode 100644 index 000000000000..39f3ab4e1be5 --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml @@ -0,0 +1,17 @@ +on: + workflow_call: + inputs: + COMMIT_SHA: + type: string + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.COMMIT_SHA }} + - run: | + npm install + npm run lint + diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_no_needs.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_no_needs.yml new file mode 100644 index 000000000000..9cc8567be7da --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_no_needs.yml @@ -0,0 +1,31 @@ +on: + pull_request_target: + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + build: + runs-on: ubuntu-latest + #needs: is-collaborator Mistake, doesn't wait for the collaborator - no security check + steps: + - name: Checkout repo + uses: actions/checkout@4 + with: + ref: ${{ github.event.pull_request.head.sha }} # should alert + fetch-depth: 2 + - run: yarn test diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable.yml new file mode 100644 index 000000000000..005fd8fb9dfc --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable.yml @@ -0,0 +1,26 @@ +on: + pull_request_target: + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + build: + needs: is-collaborator + uses: TestOrg/TestRepo/.github/workflows/build.yml@main + with: + COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permissions_check.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permissions_check.yml new file mode 100644 index 000000000000..720ca82f0b9e --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permissions_check.yml @@ -0,0 +1,31 @@ +on: + pull_request_target: + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + build: + runs-on: ubuntu-latest + needs: is-collaborator + steps: + - name: Checkout repo + uses: actions/checkout@4 + with: + ref: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check + fetch-depth: 2 + - run: yarn test diff --git a/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected b/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected index 52fcecfb9ed7..366180ef5462 100644 --- a/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected +++ b/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected @@ -93,6 +93,7 @@ edges | .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step | | .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | .github/workflows/dependabot3.yml:48:9:52:57 | Run Step | +| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:14:9:19:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step | | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:25:9:70:20 | Run Step | | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | @@ -334,6 +335,11 @@ edges | .github/workflows/untrusted_checkout_6.yml:11:9:14:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step | | .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step | | .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:21:9:23:23 | Run Step | +| .github/workflows/untrusted_checkout_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_no_needs.yml:16:9:22:2 | Run Step | +| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step | +| .github/workflows/untrusted_checkout_permission_check_reusable.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable.yml:16:9:22:2 | Run Step | +| .github/workflows/untrusted_checkout_permissions_check.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permissions_check.yml:16:9:22:2 | Run Step | +| .github/workflows/untrusted_checkout_permissions_check.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:31:9:31:23 | Run Step | | .github/workflows/workflow_run_untrusted_checkout.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout.yml:16:9:18:31 | Uses Step | | .github/workflows/workflow_run_untrusted_checkout_2.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_2.yml:16:9:18:31 | Uses Step | | .github/workflows/workflow_run_untrusted_checkout_3.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_3.yml:16:9:18:31 | Uses Step | @@ -377,3 +383,4 @@ edges | .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:47:7:51:46 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout4.yml:2:3:2:15 | issue_comment | issue_comment | | .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:15:9:18:2 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target | | .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:30:9:32:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target | +| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target | From 048884bb785a04de94df2b62f5d8beaa2dfa239c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Loba=C4=8Devski?= Date: Mon, 15 Jun 2026 06:12:45 +0000 Subject: [PATCH 2/3] Remove redundant cast --- actions/ql/lib/codeql/actions/security/ControlChecks.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index bf289b85f2d2..d7562a61895c 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -83,7 +83,7 @@ abstract class ControlCheck extends AstNode { ( this.(Step).getAFollowingStep() = node.getEnclosingStep() or - node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this.(Step) + node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this ) or // When the node is inside a reusable workflow, check if the control check @@ -105,7 +105,7 @@ abstract class ControlCheck extends AstNode { ) or (this instanceof Run or this instanceof UsesStep) and - caller.getANeededJob().(LocalJob).getAStep() = this.(Step) + caller.getANeededJob().(LocalJob).getAStep() = this ) ) } From d51a9a3e1a5183b05d83c666529e7c7001ecd08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Loba=C4=8Devski?= Date: Mon, 15 Jun 2026 06:52:13 +0000 Subject: [PATCH 3/3] Support nested reusable workflows --- .../codeql/actions/security/ControlChecks.qll | 26 ++++++++++++++++--- .../.github/workflows/build_nested.yml | 13 ++++++++++ ...ckout_permission_check_reusable_level2.yml | 26 +++++++++++++++++++ ...out_permission_check_reusable_no_needs.yml | 26 +++++++++++++++++++ .../UntrustedCheckoutCritical.expected | 3 +++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_level2.yml create mode 100644 actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll index d7562a61895c..093dd1dac16e 100644 --- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll @@ -42,6 +42,15 @@ string actor_not_attacker_event() { ] } +/** + * Gets the outer caller of `ej`, i.e. the `ExternalJob` that calls the + * reusable workflow containing `ej`. Used with transitive closure to + * walk up nested reusable workflow chains. + */ +private ExternalJob getAnOuterCaller(ExternalJob ej) { + result = ej.getEnclosingWorkflow().(ReusableWorkflow).getACaller() +} + /** An If node that contains an actor, user or label check */ abstract class ControlCheck extends AstNode { ControlCheck() { @@ -60,7 +69,12 @@ abstract class ControlCheck extends AstNode { this.getATriggerEvent() = event } + /** + * Holds if this control check must execute and pass before `node` can run. + */ predicate dominates(AstNode node) { + // Step-level: the check is an `if:` on the step containing `node`, + // or on the enclosing job, or on a needed job/step. this instanceof If and ( node.getEnclosingStep().getIf() = this or @@ -69,6 +83,7 @@ abstract class ControlCheck extends AstNode { node.getEnclosingJob().getANeededJob().(LocalJob).getIf() = this ) or + // Job-level: the check is an environment on the enclosing job or a needed job. this instanceof Environment and ( node.getEnclosingJob().getEnvironment() = this @@ -76,6 +91,8 @@ abstract class ControlCheck extends AstNode { node.getEnclosingJob().getANeededJob().getEnvironment() = this ) or + // Step-level: the check is a Run/UsesStep that precedes `node`'s step + // in the same job, or is a step in a needed job. ( this instanceof Run or this instanceof UsesStep @@ -86,10 +103,11 @@ abstract class ControlCheck extends AstNode { node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this ) or - // When the node is inside a reusable workflow, check if the control check - // dominates the caller job in the calling workflow. - exists(ExternalJob caller | - caller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and + // When the node is inside a (possibly nested) reusable workflow, + // check if the control check dominates any caller job in the chain. + exists(ExternalJob directCaller, ExternalJob caller | + directCaller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and + caller = getAnOuterCaller*(directCaller) and ( this instanceof If and ( diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested.yml new file mode 100644 index 000000000000..eaaa5616a73f --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested.yml @@ -0,0 +1,13 @@ +on: + workflow_call: + inputs: + COMMIT_SHA: + type: string + +jobs: + build: + uses: TestOrg/TestRepo/.github/workflows/build.yml@main + with: + COMMIT_SHA: ${{ inputs.COMMIT_SHA }} + + diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_level2.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_level2.yml new file mode 100644 index 000000000000..04275d981d9a --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_level2.yml @@ -0,0 +1,26 @@ +on: + pull_request_target: + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + build: + needs: is-collaborator + uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main + with: + COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check diff --git a/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml new file mode 100644 index 000000000000..0603ca64d0b0 --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml @@ -0,0 +1,26 @@ +on: + pull_request_target: + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + build: + # needs: is-collaborator + uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main + with: + COMMIT_SHA: ${{ github.event.pull_request.head.sha }} diff --git a/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected b/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected index 366180ef5462..9a544ceba2e6 100644 --- a/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected +++ b/actions/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected @@ -338,6 +338,8 @@ edges | .github/workflows/untrusted_checkout_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_no_needs.yml:16:9:22:2 | Run Step | | .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step | | .github/workflows/untrusted_checkout_permission_check_reusable.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable.yml:16:9:22:2 | Run Step | +| .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:16:9:22:2 | Run Step | +| .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:16:9:22:2 | Run Step | | .github/workflows/untrusted_checkout_permissions_check.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permissions_check.yml:16:9:22:2 | Run Step | | .github/workflows/untrusted_checkout_permissions_check.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:31:9:31:23 | Run Step | | .github/workflows/workflow_run_untrusted_checkout.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout.yml:16:9:18:31 | Uses Step | @@ -350,6 +352,7 @@ edges | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:79:9:84:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target | | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:84:9:93:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target | | .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/dependabot3.yml:3:5:3:23 | pull_request_target | pull_request_target | +| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target | | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/reusable_caller1.yaml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:21:11:23:22 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/gitcheckout.yml:2:3:2:21 | pull_request_target | pull_request_target | | .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:17:7:21:4 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/label_trusted_checkout2.yml:2:3:2:21 | pull_request_target | pull_request_target |