From 0dd3ad64d5e13f9d84fa99dc6ac19e5d27729b38 Mon Sep 17 00:00:00 2001 From: JarLob Date: Sat, 25 Jul 2026 17:58:09 +0300 Subject: [PATCH] Fixed `Schedule` event mapping --- .../config/externally_triggereable_events.yml | 2 +- .../2026-07-28-schedule-event-mapping.md | 4 ++++ .../schedule_remote_code_injection.yml | 19 +++++++++++++++++++ .../CWE-094/CodeInjectionCritical.expected | 4 ++++ .../CWE-094/CodeInjectionMedium.expected | 3 +++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md create mode 100644 actions/ql/test/query-tests/Security/CWE-094/.github/workflows/schedule_remote_code_injection.yml diff --git a/actions/ql/lib/ext/config/externally_triggereable_events.yml b/actions/ql/lib/ext/config/externally_triggereable_events.yml index ae47c684095d..2a73f4f0a6db 100644 --- a/actions/ql/lib/ext/config/externally_triggereable_events.yml +++ b/actions/ql/lib/ext/config/externally_triggereable_events.yml @@ -17,4 +17,4 @@ extensions: - ["workflow_run"] # depending on branch filter - ["workflow_call"] # depending on caller - ["workflow_dispatch"] - - ["scheduled"] + - ["schedule"] diff --git a/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md b/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md new file mode 100644 index 000000000000..ff949c266d08 --- /dev/null +++ b/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* GitHub Actions queries now correctly classify the `schedule` event when determining whether a workflow is externally triggerable. diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/schedule_remote_code_injection.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/schedule_remote_code_injection.yml new file mode 100644 index 000000000000..004a50f18e4d --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/schedule_remote_code_injection.yml @@ -0,0 +1,19 @@ +on: + schedule: + - cron: "0 0 * * *" + +permissions: + contents: write + +jobs: + fetch-issues: + runs-on: ubuntu-latest + steps: + - name: Fetch open issues + id: issues + uses: octokit/request-action@v2.x + with: + route: GET /repos/foo/bar/issues?state=open + + - name: Write issues to file + run: echo '${{ steps.issues.outputs.data }}' > issues.json \ No newline at end of file diff --git a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected index 9bf7e9aa56db..8807d1ebe57b 100644 --- a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected +++ b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected @@ -100,6 +100,7 @@ edges | .github/workflows/reusable-workflow-caller-1.yml:11:15:11:52 | github.event.pull_request.title | .github/workflows/reusable-workflow-1.yml:6:7:6:11 | input taint | provenance | | | .github/workflows/reusable-workflow-caller-2.yml:10:15:10:52 | github.event.pull_request.title | .github/workflows/reusable-workflow-2.yml:6:7:6:11 | input taint | provenance | | | .github/workflows/reusable-workflow-caller-3.yml:10:15:10:52 | github.event.pull_request.title | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable-workflow.yml:6:7:6:11 | input taint | provenance | | +| .github/workflows/schedule_remote_code_injection.yml:12:9:18:6 | Uses Step: issues | .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | provenance | | | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | provenance | | | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | provenance | | | .github/workflows/self_needs.yml:13:9:19:6 | Uses Step: source [value] | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | provenance | | @@ -460,6 +461,8 @@ nodes | .github/workflows/reusable-workflow-caller-1.yml:11:15:11:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | | .github/workflows/reusable-workflow-caller-2.yml:10:15:10:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | | .github/workflows/reusable-workflow-caller-3.yml:10:15:10:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | +| .github/workflows/schedule_remote_code_injection.yml:12:9:18:6 | Uses Step: issues | semmle.label | Uses Step: issues | +| .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | semmle.label | steps.issues.outputs.data | | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] | | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | semmle.label | steps.source.outputs.value | | .github/workflows/self_needs.yml:13:9:19:6 | Uses Step: source [value] | semmle.label | Uses Step: source [value] | @@ -777,6 +780,7 @@ subpaths | .github/workflows/reusable-workflow-2.yml:36:21:36:39 | inputs.taint | .github/workflows/reusable-workflow-caller-2.yml:10:15:10:52 | github.event.pull_request.title | .github/workflows/reusable-workflow-2.yml:36:21:36:39 | inputs.taint | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/reusable-workflow-2.yml:36:21:36:39 | inputs.taint | ${{ inputs.taint }} | .github/workflows/reusable-workflow-caller-2.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/reusable-workflow-2.yml:53:26:53:39 | env.log | .github/workflows/reusable-workflow-2.yml:44:19:44:56 | github.event.pull_request.title | .github/workflows/reusable-workflow-2.yml:53:26:53:39 | env.log | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/reusable-workflow-2.yml:53:26:53:39 | env.log | ${{ env.log }} | .github/workflows/reusable-workflow-caller-2.yml:4:3:4:21 | pull_request_target | pull_request_target | | .github/workflows/reusable-workflow-2.yml:66:34:66:52 | env.prev_log | .github/workflows/reusable-workflow-2.yml:45:24:45:61 | github.event.changes.title.from | .github/workflows/reusable-workflow-2.yml:66:34:66:52 | env.prev_log | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/reusable-workflow-2.yml:66:34:66:52 | env.prev_log | ${{ env.prev_log }} | .github/workflows/reusable-workflow-caller-2.yml:4:3:4:21 | pull_request_target | pull_request_target | +| .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | .github/workflows/schedule_remote_code_injection.yml:12:9:18:6 | Uses Step: issues | .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | ${{ steps.issues.outputs.data }} | .github/workflows/schedule_remote_code_injection.yml:2:3:2:10 | schedule | schedule | | .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | .github/workflows/self_needs.yml:16:20:16:57 | github.event['comment']['body'] | .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/self_needs.yml:19:15:19:47 | steps.source.outputs.value | ${{ steps.source.outputs.value }} | .github/workflows/self_needs.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | .github/workflows/self_needs.yml:16:20:16:57 | github.event['comment']['body'] | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | ${{ needs.test1.outputs.job_output }} | .github/workflows/self_needs.yml:4:3:4:15 | issue_comment | issue_comment | | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | .github/workflows/simple2.yml:14:9:18:6 | Uses Step: source | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/simple2.yml:29:24:29:54 | steps.step.outputs.value | ${{ steps.step.outputs.value }} | .github/workflows/simple2.yml:3:6:3:24 | pull_request_target | pull_request_target | diff --git a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected index 4bbe7da0aaf3..bbf8b0dec557 100644 --- a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected +++ b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionMedium.expected @@ -100,6 +100,7 @@ edges | .github/workflows/reusable-workflow-caller-1.yml:11:15:11:52 | github.event.pull_request.title | .github/workflows/reusable-workflow-1.yml:6:7:6:11 | input taint | provenance | | | .github/workflows/reusable-workflow-caller-2.yml:10:15:10:52 | github.event.pull_request.title | .github/workflows/reusable-workflow-2.yml:6:7:6:11 | input taint | provenance | | | .github/workflows/reusable-workflow-caller-3.yml:10:15:10:52 | github.event.pull_request.title | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable-workflow.yml:6:7:6:11 | input taint | provenance | | +| .github/workflows/schedule_remote_code_injection.yml:12:9:18:6 | Uses Step: issues | .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | provenance | | | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | .github/workflows/self_needs.yml:20:15:20:51 | needs.test1.outputs.job_output | provenance | | | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | provenance | | | .github/workflows/self_needs.yml:13:9:19:6 | Uses Step: source [value] | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | provenance | | @@ -460,6 +461,8 @@ nodes | .github/workflows/reusable-workflow-caller-1.yml:11:15:11:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | | .github/workflows/reusable-workflow-caller-2.yml:10:15:10:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | | .github/workflows/reusable-workflow-caller-3.yml:10:15:10:52 | github.event.pull_request.title | semmle.label | github.event.pull_request.title | +| .github/workflows/schedule_remote_code_injection.yml:12:9:18:6 | Uses Step: issues | semmle.label | Uses Step: issues | +| .github/workflows/schedule_remote_code_injection.yml:19:21:19:52 | steps.issues.outputs.data | semmle.label | steps.issues.outputs.data | | .github/workflows/self_needs.yml:11:7:12:4 | Job outputs node [job_output] | semmle.label | Job outputs node [job_output] | | .github/workflows/self_needs.yml:11:20:11:52 | steps.source.outputs.value | semmle.label | steps.source.outputs.value | | .github/workflows/self_needs.yml:13:9:19:6 | Uses Step: source [value] | semmle.label | Uses Step: source [value] |