diff --git a/ql/lib/codeql/actions/security/ControlChecks.qll b/ql/lib/codeql/actions/security/ControlChecks.qll index b9410f0fcb0..134ce780eee 100644 --- a/ql/lib/codeql/actions/security/ControlChecks.qll +++ b/ql/lib/codeql/actions/security/ControlChecks.qll @@ -99,9 +99,6 @@ abstract class RepositoryCheck extends ControlCheck { // for pull_requests, that means that it triggers only on local branches or repos from the same org // - they are effective against pull requests/workflow_run since they can control where the code is coming from // - they are not effective against issue_comment since the repository will always be the same - override predicate protectsCategoryAndEvent(string category, string event) { - event = ["pull_request_target", "workflow_run"] and category = any_relevant_category() - } } abstract class PermissionCheck extends ControlCheck { @@ -173,9 +170,9 @@ class ActorIfCheck extends ActorCheck instanceof If { } } -class RepositoryIfCheck extends RepositoryCheck instanceof If { - RepositoryIfCheck() { - // eg: github.repository == 'test/foo' +class PullRequestTargetRepositoryIfCheck extends RepositoryCheck instanceof If { + PullRequestTargetRepositoryIfCheck() { + // eg: github.event.pull_request.head.repo.full_name == github.repository exists( normalizeExpr(this.getCondition()) // github.repository in a workflow_run event triggered by a pull request is the base repository @@ -188,6 +185,28 @@ class RepositoryIfCheck extends RepositoryCheck instanceof If { ], _, _) ) } + + override predicate protectsCategoryAndEvent(string category, string event) { + event = "pull_request_target" and category = any_relevant_category() + } +} + +class WorkflowRunRepositoryIfCheck extends RepositoryCheck instanceof If { + WorkflowRunRepositoryIfCheck() { + // eg: github.event.workflow_run.head_repository.full_name == github.repository + exists( + normalizeExpr(this.getCondition()) + // github.repository in a workflow_run event triggered by a pull request is the base repository + .regexpFind([ + "\\bgithub\\.event\\.workflow_run\\.head_repository\\.full_name\\b", + "\\bgithub\\.event\\.workflow_run\\.head_repository\\.owner\\.name\\b" + ], _, _) + ) + } + + override predicate protectsCategoryAndEvent(string category, string event) { + event = "workflow_run" and category = any_relevant_category() + } } class AssociationIfCheck extends AssociationCheck instanceof If { diff --git a/ql/test/query-tests/Security/CWE-077/.github/workflows/test11.yml b/ql/test/query-tests/Security/CWE-077/.github/workflows/test11.yml index 2c2480f5353..5edd526d820 100644 --- a/ql/test/query-tests/Security/CWE-077/.github/workflows/test11.yml +++ b/ql/test/query-tests/Security/CWE-077/.github/workflows/test11.yml @@ -8,37 +8,11 @@ on: jobs: comment: - if: ${{ github.repository_owner == 'cloudflare' }} + if: ${{ github.repository_owner == 'foo' }} runs-on: ubuntu-latest name: Write comment to the PR steps: - - name: "Put PR and workflow ID on the environment" - uses: actions/github-script@v7 - with: - script: | - // Copied from .github/extract-pr-and-workflow-id.js - const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - for (const artifact of allArtifacts.data.artifacts) { - // Extract the PR number from the artifact name - const match = /^npm-package-(.+)-(\d+)$/.exec(artifact.name); - if (match) { - const packageName = match[1].toUpperCase(); - require("fs").appendFileSync( - process.env.GITHUB_ENV, - `\nWORKFLOW_RUN_PR_FOR_${packageName}=${match[2]}` + - `\nWORKFLOW_RUN_ID_FOR_${packageName}=${context.payload.workflow_run.id}` - ); - } - } - - name: "Download runtime versions" - # Regular `actions/download-artifact` doesn't support downloading - # artifacts from another workflow uses: dawidd6/action-download-artifact@v2 with: run_id: ${{ github.event.workflow_run.id }} @@ -52,30 +26,3 @@ jobs: cat runtime-versions.md echo EOF } >> "$GITHUB_ENV" - - - name: "Download pre-release report" - uses: dawidd6/action-download-artifact@v2 - with: - run_id: ${{ github.event.workflow_run.id }} - name: prerelease-report.md - - - name: "Put pre-release report on the environment" - id: prerelease_report - run: | - { - echo 'PRERELEASE_REPORT<> "$GITHUB_ENV" - - - name: "Comment on PR with Wrangler link" - uses: marocchino/sticky-pull-request-comment@v2 - with: - number: ${{ env.WORKFLOW_RUN_PR_FOR_WRANGLER }} - message: | - ${{ env.PRERELEASE_REPORT }} - - --- - - ${{ env.RUNTIME_VERSIONS }} - diff --git a/ql/test/query-tests/Security/CWE-077/EnvVarInjectionCritical.expected b/ql/test/query-tests/Security/CWE-077/EnvVarInjectionCritical.expected index cbd17161942..6ad5cf04304 100644 --- a/ql/test/query-tests/Security/CWE-077/EnvVarInjectionCritical.expected +++ b/ql/test/query-tests/Security/CWE-077/EnvVarInjectionCritical.expected @@ -20,10 +20,7 @@ edges | .github/workflows/test8.yml:26:9:32:6 | Uses Step | .github/workflows/test8.yml:40:14:41:79 | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | provenance | | | .github/workflows/test9.yml:19:9:27:6 | Uses Step | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | provenance | | | .github/workflows/test10.yml:20:9:26:6 | Uses Step | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:49:14:54:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:56:9:62:6 | Uses Step | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | -| .github/workflows/test11.yml:56:9:62:6 | Uses Step | .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | +| .github/workflows/test11.yml:15:9:21:6 | Uses Step | .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:55:9:61:6 | Uses Step | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | @@ -69,10 +66,8 @@ nodes | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | | .github/workflows/test10.yml:20:9:26:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | semmle.label | cat foo/.github/java-config.env >> $GITHUB_ENV | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | semmle.label | Uses Step | -| .github/workflows/test11.yml:49:14:54:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | -| .github/workflows/test11.yml:56:9:62:6 | Uses Step | semmle.label | Uses Step | -| .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | +| .github/workflows/test11.yml:15:9:21:6 | Uses Step | semmle.label | Uses Step | +| .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:55:9:61:6 | Uses Step | semmle.label | Uses Step | @@ -100,6 +95,7 @@ subpaths | .github/workflows/test8.yml:40:14:41:79 | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | .github/workflows/test8.yml:26:9:32:6 | Uses Step | .github/workflows/test8.yml:40:14:41:79 | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test8.yml:40:14:41:79 | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | .github/workflows/test9.yml:19:9:27:6 | Uses Step | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | .github/workflows/test10.yml:20:9:26:6 | Uses Step | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | cat foo/.github/java-config.env >> $GITHUB_ENV | +| .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | .github/workflows/test11.yml:15:9:21:6 | Uses Step | .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | .github/workflows/test12.yml:55:9:61:6 | Uses Step | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | Potential environment variable injection in $@, which may be controlled by an external user. | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | diff --git a/ql/test/query-tests/Security/CWE-077/EnvVarInjectionMedium.expected b/ql/test/query-tests/Security/CWE-077/EnvVarInjectionMedium.expected index e780af4107d..82602ee8ed8 100644 --- a/ql/test/query-tests/Security/CWE-077/EnvVarInjectionMedium.expected +++ b/ql/test/query-tests/Security/CWE-077/EnvVarInjectionMedium.expected @@ -20,10 +20,7 @@ edges | .github/workflows/test8.yml:26:9:32:6 | Uses Step | .github/workflows/test8.yml:40:14:41:79 | echo "foo=$(< /artifacts/parent-artifacts/event.txt)" >> $GITHUB_ENV\n | provenance | | | .github/workflows/test9.yml:19:9:27:6 | Uses Step | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | provenance | | | .github/workflows/test10.yml:20:9:26:6 | Uses Step | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:49:14:54:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:56:9:62:6 | Uses Step | provenance | | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | -| .github/workflows/test11.yml:56:9:62:6 | Uses Step | .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | +| .github/workflows/test11.yml:15:9:21:6 | Uses Step | .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:55:9:61:6 | Uses Step | provenance | | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | .github/workflows/test12.yml:63:14:68:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | provenance | | @@ -69,10 +66,8 @@ nodes | .github/workflows/test9.yml:29:14:41:41 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_ENV\necho "ref=$ref" >> $GITHUB_ENV\n | | .github/workflows/test10.yml:20:9:26:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test10.yml:27:14:27:59 | cat foo/.github/java-config.env >> $GITHUB_ENV | semmle.label | cat foo/.github/java-config.env >> $GITHUB_ENV | -| .github/workflows/test11.yml:39:9:47:6 | Uses Step | semmle.label | Uses Step | -| .github/workflows/test11.yml:49:14:54:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | -| .github/workflows/test11.yml:56:9:62:6 | Uses Step | semmle.label | Uses Step | -| .github/workflows/test11.yml:64:14:69:29 | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'PRERELEASE_REPORT<> "$GITHUB_ENV"\n | +| .github/workflows/test11.yml:15:9:21:6 | Uses Step | semmle.label | Uses Step | +| .github/workflows/test11.yml:23:14:28:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:38:9:46:6 | Uses Step | semmle.label | Uses Step | | .github/workflows/test12.yml:48:14:53:29 | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | semmle.label | {\n echo 'RUNTIME_VERSIONS<> "$GITHUB_ENV"\n | | .github/workflows/test12.yml:55:9:61:6 | Uses Step | semmle.label | Uses Step | diff --git a/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout2.yml b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout2.yml index d9e5d6be670..47a0dfc6bd3 100644 --- a/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout2.yml +++ b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout2.yml @@ -6,7 +6,7 @@ jobs: steps: - name: Get PR number id: pr_number - if: ${{ github.event_name == 'issue_comment'}} + if: github.event_name == 'issue_comment' && github.repository_owner == 'foo' run: | PR_URL="${{ github.event.issue.pull_request.url }}" PR_NUMBER=${PR_URL##*/} diff --git a/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_5.yml b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_5.yml new file mode 100644 index 00000000000..b98d7654998 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_5.yml @@ -0,0 +1,23 @@ +on: + pull_request_target + +jobs: + build: + runs-on: ubuntu-latest + if: github.repository_owner == 'foo' + env: + HEAD: ${{ github.event.pull_request.head.sha }} + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD }} + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + - run: | + npm install + npm run lint diff --git a/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_6.yml b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_6.yml new file mode 100644 index 00000000000..037a0eb79f9 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-829/.github/workflows/untrusted_checkout_6.yml @@ -0,0 +1,23 @@ +on: + pull_request_target + +jobs: + build: + runs-on: ubuntu-latest + if: github.event.pull_request.head.repo.full_name == github.repository + env: + HEAD: ${{ github.event.pull_request.head.sha }} + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD }} + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + - run: | + npm install + npm run lint diff --git a/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_2.yml b/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_2.yml new file mode 100644 index 00000000000..bcde60f55cb --- /dev/null +++ b/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_2.yml @@ -0,0 +1,19 @@ +on: + workflow_run: + workflows: ['Test'] + types: [completed] + +jobs: + build: + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == "success" && github.repository_owner == 'foo' + env: + HEAD: ${{ github.event.workflow_run.head.sha }} + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.workflow_run.head.sha }} + - uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD }} + diff --git a/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_3.yml b/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_3.yml new file mode 100644 index 00000000000..55aa0b41c6c --- /dev/null +++ b/ql/test/query-tests/Security/CWE-829/.github/workflows/workflow_run_untrusted_checkout_3.yml @@ -0,0 +1,19 @@ +on: + workflow_run: + workflows: ['Test'] + types: [completed] + +jobs: + build: + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == "success" && github.event.workflow_run.head_repository.full_name == github.repository + env: + HEAD: ${{ github.event.workflow_run.head.sha }} + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.workflow_run.head.sha }} + - uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD }} + diff --git a/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected b/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected index 4dc2b53e591..f20fdc79829 100644 --- a/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected +++ b/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutCritical.expected @@ -262,7 +262,15 @@ edges | .github/workflows/untrusted_checkout.yml:10:9:13:6 | Uses Step | .github/workflows/untrusted_checkout.yml:13:9:16:6 | Uses Step | | .github/workflows/untrusted_checkout.yml:13:9:16:6 | Uses Step | .github/workflows/untrusted_checkout.yml:16:9:20:6 | Uses Step | | .github/workflows/untrusted_checkout.yml:16:9:20:6 | Uses Step | .github/workflows/untrusted_checkout.yml:20:9:22:23 | Run Step | +| .github/workflows/untrusted_checkout_5.yml:11:9:14:6 | Uses Step | .github/workflows/untrusted_checkout_5.yml:14:9:17:6 | Uses Step | +| .github/workflows/untrusted_checkout_5.yml:14:9:17:6 | Uses Step | .github/workflows/untrusted_checkout_5.yml:17:9:21:6 | Uses Step | +| .github/workflows/untrusted_checkout_5.yml:17:9:21:6 | Uses Step | .github/workflows/untrusted_checkout_5.yml:21:9:23:23 | Run Step | +| .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/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 | #select | .github/reusable_workflows/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | .github/reusable_workflows/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/reusable_workflows/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | Execution of untrusted code on a privileged workflow. $@ | .github/workflows/reusable_caller1.yaml:4:3:4:21 | pull_request_target | .github/workflows/reusable_caller1.yaml | | .github/workflows/actor_trusted_checkout.yml:15:7:19:4 | Run Step | .github/workflows/actor_trusted_checkout.yml:9:7:14:4 | Uses Step | .github/workflows/actor_trusted_checkout.yml:15:7:19:4 | Run Step | Execution of untrusted code on a privileged workflow. $@ | .github/workflows/actor_trusted_checkout.yml:2:3:2:21 | pull_request_target | .github/workflows/actor_trusted_checkout.yml | diff --git a/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutHigh.expected b/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutHigh.expected index 81a8c63c882..1d6122b3747 100644 --- a/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutHigh.expected +++ b/ql/test/query-tests/Security/CWE-829/UntrustedCheckoutHigh.expected @@ -18,3 +18,5 @@ | .github/workflows/untrusted_checkout2.yml:14:9:19:72 | Run Step | Potential execution of untrusted code on a privileged workflow. | | .github/workflows/workflow_run_untrusted_checkout.yml:13:9:16:6 | Uses Step | Potential execution of untrusted code on a privileged workflow. | | .github/workflows/workflow_run_untrusted_checkout.yml:16:9:18:31 | Uses Step | Potential execution of untrusted code on a privileged workflow. | +| .github/workflows/workflow_run_untrusted_checkout_2.yml:13:9:16:6 | Uses Step | Potential execution of untrusted code on a privileged workflow. | +| .github/workflows/workflow_run_untrusted_checkout_2.yml:16:9:18:31 | Uses Step | Potential execution of untrusted code on a privileged workflow. |