Do not consider priv events if runtime data is available

This commit is contained in:
Alvaro Muñoz
2024-06-23 21:34:30 +02:00
parent 4e94c4294c
commit 6df70d1a45
3 changed files with 58 additions and 5 deletions

View File

@@ -853,6 +853,14 @@ class JobImpl extends AstNodeImpl, TJobNode {
this.getEnclosingWorkflow().getPermissions().getAPermission().matches("%write")
}
private predicate hasRuntimeData() {
exists(string path, string trigger, string name, string secrets_source, string perms |
workflowDataModel(path, trigger, name, secrets_source, perms, _) and
path.trim() = this.getLocation().getFile().getRelativePath() and
name.trim().matches(this.getId() + "%")
)
}
private predicate hasRuntimeWritePermissions() {
// the effective runtime permissions have write access
exists(string path, string trigger, string name, string secrets_source, string perms |
@@ -885,15 +893,18 @@ class JobImpl extends AstNodeImpl, TJobNode {
/** Holds if the action is privileged and externally triggerable. */
predicate isPrivilegedExternallyTriggerable() {
exists(EventImpl e |
// job is triggereable by an external user
this.getATriggerEvent() = e and
// job is triggereable by an external user
e.isExternallyTriggerable() and
// job is privileged (write access or access to secrets)
// no matter if `pull_request` is granted write permissions or access to secrets
// when the job is triggered by a `pull_request` event from a fork, they will get revoked
not e.getName() = "pull_request" and
(
this.isPrivileged() and
not e.getName() = "pull_request"
// job is privileged (write access or access to secrets)
this.isPrivileged()
or
not this.isPrivileged() and
// the trigger event is __normally__ privileged and we have no runtime data to prove otherwise
not this.hasRuntimeData() and
e.isPrivileged()
)
)

View File

@@ -0,0 +1,41 @@
name: "Test"
permissions:
actions: none
checks: none
contents: read
deployments: none
id-token: none
issues: none
discussions: none
packages: none
pages: none
pull-requests: read
repository-projects: none
security-events: none
statuses: none
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Test Pull Request
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- run: npm install
working-directory: scripts/github-actions/semantic-pull-request/
- name: Lint PR Title
if: github.event_name == 'pull_request_target'
uses: actions/github-script@v7
with:
script: |
const verifyPullRequest = require('./scripts/github-actions/semantic-pull-request')
await verifyPullRequest({ context, core, github })

View File

@@ -4,5 +4,6 @@
| .github/workflows/level0.yml:99:9:103:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/level0.yml:125:9:129:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/untrusted_checkout.yml:10:9:13:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/untrusted_checkout.yml:13:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |