diff --git a/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql b/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql index a8bd8a5f93dc..00f601fd5daf 100644 --- a/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql +++ b/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql @@ -26,10 +26,23 @@ string permissionsForJob(Job job) { "{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}" } +predicate jobHasPermissions(Job job) { + exists(job.getPermissions()) + or + exists(job.getEnclosingWorkflow().getPermissions()) + or + // The workflow is reusable and cannot be triggered in any other way; check callers + exists(ReusableWorkflow r | r = job.getEnclosingWorkflow() | + not exists(Event e | e = r.getOn().getAnEvent() | e.getName() != "workflow_call") and + forall(Job caller | caller = job.getEnclosingWorkflow().(ReusableWorkflow).getACaller() | + jobHasPermissions(caller) + ) + ) +} + from Job job, string permissions where - not exists(job.getPermissions()) and - not exists(job.getEnclosingWorkflow().getPermissions()) and + not jobHasPermissions(job) and // exists a trigger event that is not a workflow_call exists(Event e | e = job.getATriggerEvent() and diff --git a/actions/ql/src/change-notes/2026-04-02-permissions.md b/actions/ql/src/change-notes/2026-04-02-permissions.md new file mode 100644 index 000000000000..2672a30ef870 --- /dev/null +++ b/actions/ql/src/change-notes/2026-04-02-permissions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions. \ No newline at end of file diff --git a/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms11.yml b/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms11.yml new file mode 100644 index 000000000000..717cdabc3025 --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms11.yml @@ -0,0 +1,9 @@ +on: + workflow_call: + +jobs: + build: + name: Build and test + runs-on: ubuntu-latest + steps: + - uses: actions/deploy-pages diff --git a/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms12.yml b/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms12.yml new file mode 100644 index 000000000000..25ac1f532481 --- /dev/null +++ b/actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms12.yml @@ -0,0 +1,11 @@ +on: + workflow_dispatch: + +permissions: + contents: read + id-token: write + pages: write + +jobs: + call-workflow: + uses: ./.github/workflows/perms11.yml