Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

polarathene
Copy link
Member

@polarathene polarathene commented Nov 15, 2024

Description

This should restore our docs preview workflow to be compatible with PRs from forks.

Context

Originally we had compatibility with PRs from forks with the pull_request event workflow, but relied on passing the PR metadata via ENV in a file that the PR author could manipulate which was a security risk.


Change overview

Changes from pull_request (untrusted) + workflow_run (trusted) workflows, to use a pull_request_target workflow with separate prepare (untrusted) + deploy (trusted) re-usable workflows managed.

  • docs-preview.yml is now the entrypoint (via pull_request_target event trigger).
  • prepare + deploy receive any configurables and secrets via inputs (JSON) from docs-preview.yml.
  • Care has been taken to ensure that pull_request_target can safely be used to build the PR in a restricted trust environment. The only secret available is GITHUB_TOKEN with minimal permissions, but this should not be accessible to the contributor as their PR cannot modify this workflow like they could with pull_request event based workflows, and the actions/checkout step uses persist-credentials: false to ensure it's accidentally stored on disk.
  • With this approach we no longer have two separate workflow runs to provide the docs preview functionality. This simplifies the actions/downloads step and removes the need for commit status management to have a check suite status for the workflow_run workflow previously used.

docs-preview-prepare.yml + docs-preview-deploy.yml provide re-usable workflows (workflow_call trigger) instead of inline jobs in docs-preview to minimize permissions and secrets to each job accordingly. It also hopefully communicates the distinction of untrusted vs trusted contexts for maintainers.

Type of change

  • Improvement (non-breaking change that does improve existing functionality)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • New and existing unit tests pass locally with my changes
  • I have added information about changes made in this PR to CHANGELOG.md

@polarathene
Copy link
Member Author

Pinging @pwntester for review 🙏

Copy link
Member Author

@polarathene polarathene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Context if it helps work through the review faster :)

Comment on lines +4 to +22
workflow_call:
inputs:
preview-context:
description: 'Preview Metadata (JSON)'
required: true
type: string
secrets:
NETLIFY_AUTH_TOKEN:
required: true
NETLIFY_SITE_ID:
required: true

env:
BUILD_DIR: ${{ fromJSON( inputs.preview-context ).build_dir }}
# PR head SHA (latest commit):
PR_HEADSHA: ${{ fromJSON( inputs.preview-context ).pull_request.head_sha }}
PR_NUMBER: ${{ fromJSON( inputs.preview-context ).pull_request.number }}
# Deploy URL preview prefix (the site name for the prefix is managed at Netlify):
PREVIEW_SITE_PREFIX: ${{ fromJSON( inputs.preview-context ).netlify.deploy_prefix }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both workflows should be fairly easy to grok now with inputs / env hoisted up to the top of the workflow.

Let me know if you disagree with the JSON input approach. I could make each one a separate input instead, but that seemed redundant and would just add more noise?

Comment on lines +25 to +47
# Common inputs shared between the two workflow jobs (`preview` + `deploy`).
# Composed as JSON to pass as a single input which each called job will map into separate ENV for use.
env:
PREVIEW_CONTEXT: |
{
"build_dir": "docs/site/",
"netlify": {
"site_name": "dms-doc-previews",
"deploy_prefix": "pullrequest-${{ github.event.pull_request.number }}"
},
"pull_request": {
"head_repo": "${{ github.event.pull_request.head.repo.full_name }}",
"head_sha": "${{ github.event.pull_request.head.sha }}",
"number": "${{ github.event.pull_request.number }}"
}
}
# Grant `secrets.GITHUB_TOKEN` only the minimum permissions needed by actions to function:
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token
# NOTE: See the associated `preview` and `deploy` workflows called for when these permissions are needed.
permissions:
contents: read
pull-requests: write
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the only "dynamic" config for the workflow. Not sure if the repo.full_name context could be used here for manipulation?

permissions has been limited accordingly. The prepare workflow that later runs the PR branch to build the docs only has contents: read available, but AFAIK should not have access to GITHUB_TOKEN on the PR author's side of things and they no longer have influence over the workflow itself.

That only leaves build-docs.sh as a concern, but with the restricted permissions for GITHUB_TOKEN and preventing any secrets from being in scope via workflow_call trigger, I think it's very close to the restricted environment of pull_request event triggered workflows? (provided any future additions don't introduce risks in docs-preview-prepare.yml)

Comment on lines 72 to 89
# The `prepare` job is for running steps in an untrusted context (necessary to build the docs):
# CAUTION: This runs a build script which the PR could modify for malicious purposes.
prepare:
needs: [create-context]
uses: docker-mailserver/docker-mailserver/.github/workflows/docs-preview-prepare.yml@main
with:
preview-context: ${{ needs.create-context.outputs.preview-context }}

# The `deploy` job is for running the remaining steps in a trusted context after building the PR branch:
# CAUTION: Do not execute any content from untrusted sources (the PR branch or the retrieved artifact from the `prepare` job)
deploy:
needs: [create-context, prepare]
uses: docker-mailserver/docker-mailserver/.github/workflows/docs-preview-deploy.yml@main
secrets:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
with:
preview-context: ${{ needs.create-context.outputs.preview-context }}
Copy link
Member Author

@polarathene polarathene Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presently the prepare + deploy jobs here have uses with an explicit <org>/<repo> ... @<branch> value.

I could relax that to omit those. PRs for branches from forks would not run changes on those branches AFAIK so that'd be ok. Might be better for any future maintenance to run the PR change, but I'm not sure how that may affect PRs from forks, especially with pull_request_target, it'd be the workflow from the PR base branch (which most of the time would be master).

EDIT: Fixed the @main refs to point to @master via follow-up commit.

Comment on lines +36 to +38
# Prevent `secrets.GITHUB_TOKEN` from being stored in a `.git/config` file, which could otherwise
# be compromised when executing untrusted code from a PR (as is done in the build step below).
persist-credentials: false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, my understanding is the equivalent of secrets.GITHUB_TOKEN would be stored in .git/config, so whatever permissions grant, the PR author could leverage for malicious intent should they gain access to the token.

I'm not sure how many other actions may cache the token, or other secrets by default like actions/checkout does implicitly. I don't think we would have many scenarios for workflows requiring to execute untrusted third-party content + access to secrets... presumably this is mostly a concern for PR oriented workflows when pull_request isn't sufficient?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token is available to an attacker by dumping the runner memory so you need to assume that the attacker will be able to get Pull Request write permissions
https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/

The safest approach is to run all untrusted code in a pull_request triggered workflow and pass any needed information to a workflow_run privileged workflow but verifying this information to make sure its the expected one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token is available to an attacker by dumping the runner memory

Are you saying that persist-credentials: false is not worthwhile then?

EDIT: I have dumped memory as explained in the linked article and can confirm if those commands can be run then it's possible to get the GH token that way too 👍


you need to assume that the attacker will be able to get Pull Request write permissions

I don't understand how the attacker would get these permissions. pull_request_target does have those permissions, but this prepare job that calls the docs-preview-prepare.yml workflow is via a separate runner instance and has permissions set to only contents: read.

So while it is grouped under the same workflow run ID it should not have the calling workflow (docs-preview.yml) token in memory? Was this a misunderstanding during your review?


The safest approach is to run all untrusted code in a pull_request triggered workflow and pass any needed information to a workflow_run privileged workflow but verifying this information to make sure its the expected one.

I don't mind taking that approach, and I do agree with you that pull_request + workflow_run is the approach I would generally advise anyone else due to the risks of pull_request_target, but I would appreciate clarification on what I've done with this PR that does not mirror the equivalent pull_request environment for running docs-preview-prepare.yml?

The default permissions for pull_request when the PR is from a fork, to my knowledge is read for all scopes, while secrets is none? Have I not secured docs-preview-prepare.yml in the same way by restricting permissions and secrets via this separate workflow_call workflow?

Is there something else that pull_request does differently to be more secure?


With pull_request_target the PR author cannot modify the workflow that is run, unlike pull_request.

Presently that benefit isn't relevant due to build-docs.sh, but otherwise the build process would be sandboxed within the Docker container used, thus even if the build process was manipulated (eg: compromise via Docker image or it's dependencies), it is very unlikely an attack could then affect something on the Docker host (runner) provided our only interaction with the build output is via artifact upload/download of the build directory.

Comment on lines +44 to +45
# CAUTION: Security risk due to executing `build-docs.sh` (which a PR could modify to be malicious):
# Care must be taken to run this workflow as if it were in an untrusted context (like the `on: pull_request` event trigger would).
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason we allow this is so that an update to the Docker image tag via PR would trigger the workflow to detect any breakage to docs generation.

I could make another workflow_call workflow file for this instead (docs-production-deploy.yml requires calling build-docs.sh too), and perhaps with uses: excluding the repo and branch pin, we'd still be able to verify that version bump PR works correctly 🤔

@polarathene
Copy link
Member Author

polarathene commented Nov 16, 2024

Alternative

I recently came across how another project chose to resolve the PR metadata concern: zizmorcore/zizmor#156 (comment)

From the links referenced diff:

pull_request workflow:

      - name: Save PR number
        run: |
          echo "${{ github.event.number }}" > .pr_number

workflow_run workflow:

      - name: Validate and set PR number
        run: |
          PR_NUMBER=$(cat docs-preview/.pr_number)
          if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
            echo "Invalid PR number: $PR_NUMBER"
            exit 1
          fi
          echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV

Notes:

  • As an additional precaution the above approach store values per variable into individual files, and validate the values (eg only digits for a PR number). The ENV key is only set explicitly for $GITHUB_ENV in workflow_run, which with validation should avoid the vulnerability concern of malicious changes slipping through.
  • Minor issue that valid values could still be manipulated by the PR author, but I've since been made aware that we can now enforce requiring approval to run workflows for external contributors (only valid for pull_request triggers).

UPDATE: I assisted another project to apply this approach: nonebot/nonebot2#3124


Potential improvement. Instead of $GITHUB_ENV in the workflow_run portion, it could be changed to $GITHUB_OUTPUT, using step outputs instead of the env context.

It may be worth considering the above as an alternative to what this PR proposes with pull_request_target.

  • We only need the PR number and head SHA, and BUILD_DIR is static.
  • The approval for PRs from forks is only for the pull_request event, while pull_request_target would allow the PR author to always run build-docs.sh to execute code without our approval, unless we address that.

@georglauterbach
Copy link
Member

I had a somewhat superficial review because this is rather intricate, and I lack the time to perform an in-depth investigation. The changes look good to me, and when you resolve some of the discussions you started yourself (branch names, etc.), I think we can ship this.

I cannot give an opinion on #4264 (comment). Unless you implement it because you know it's better, I'd go with the current set of changes.

@polarathene
Copy link
Member Author

I cannot give an opinion on #4264 (comment). Unless you implement it because you know it's better, I'd go with the current set of changes.

That alternative is to revert back to our original pull_request + workflow_run approach passing the equivalent workflow_call.inputs / JSON via artifact upload/download again.

  • It'd just use $GITHUB_OUTPUT instead of $GITHUB_ENV, which avoids any concern for LD_PRELOAD. But we could also be a be a bit more specific and add validation.
  • The PR author could still manipulate the PR number or SHA via modifying the pull_request workflow. It won't have any known vulnerability to exploit anymore, but we'd probably want to consider always requiring approval to run the workflow as a added precaution 🤔

I'm personally not a fan of the old approach we had.

  • I find the approach I've proposed here with pull_request_target + workflow_call is more intuitive to follow (pull_request_target directly calls the preview + deploy workflows, rather than workflow_run implicitly triggered by pull_request workflow).
  • The new approach doesn't need to use additional actions to manage the check suite status to report success/failure of the deployment.
  • The required inputs are clearer to the maintainers, with the workflow_call workflows (prepare + deploy) defining these right at the top, while the shared context for those inputs are managed at the parent workflow pull_request_target (docs-preview.yml).
  • PR authors cannot manipulate these workflows.

However this is not an approach I'd contribute to other projects as there is some risk if maintainers make changes to the workflow without care. The pull_request + workflow_run approach can be a little inconvenient, but is technically safer.

To my knowledge docs-preview-prepare.yml should be roughly equivalent in safety to pull_request, provided permissions are locked down (defaults AFAIK is read for everything, even for PRs from forks from non-collaborators) and secrets remains at none (unfortunately it's not possible to enforce that expectation). So long as docs-preview-prepare.yml is treated as if it were the equivalent pull_request workflow, all is well 😅

# CAUTION: This runs a build script which the PR could modify for malicious purposes.
prepare:
needs: [create-context]
uses: docker-mailserver/docker-mailserver/.github/workflows/docs-preview-prepare.yml@master

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job is running untrusted code in the context of pull_request_target. There are no secrets shared with the job and only Pull Request write permissions so the risk is low, however there is still some risk. Cant this be moved to a pull_request workflow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job is running untrusted code in the context of pull_request_target. There are no secrets shared with the job and only Pull Request write permissions so the risk is low,

It should only have contents: read permission. I know that it inherits from this pull_request_target permissions which have been limited, but the prepare workflow_call itself is restricted to only contents: read, pull_requests: write is for the separate deploy workflow_call.

The calling workflow docs-preview.yml / pull_request_target must grant these permissions as the sub-workflows called can only reduce the permissions scope, not add extra permissions.

Unfortunately docs-preview-prepare.yml cannot enforce secrets: none, so there is potential risk there should a maintainer call the workflow with secrets: inherit or pass a secret through.


Cant this be moved to a pull_request workflow?

That's what it was before this PR.

  • This PR has 3 workflow files, but is run as a single workflow run.
  • The approach prior to this is pull_request + workflow_run, two separate workflow files, but also treated as two separate workflow runs on the actions tab, and that complicates the management a bit with PR context + commit status management.

If we change back to pull_request, I need to run the deploy job with access to secrets and the PR metadata (the number to write the PR comment with preview link). Originally as you know we had a vulnerability there with how the PR metadata as passed via artifact and loaded into ENV, so there is still potential risk.

Comment on lines +36 to +38
# Prevent `secrets.GITHUB_TOKEN` from being stored in a `.git/config` file, which could otherwise
# be compromised when executing untrusted code from a PR (as is done in the build step below).
persist-credentials: false

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token is available to an attacker by dumping the runner memory so you need to assume that the attacker will be able to get Pull Request write permissions
https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/

The safest approach is to run all untrusted code in a pull_request triggered workflow and pass any needed information to a workflow_run privileged workflow but verifying this information to make sure its the expected one.

Copy link
Member Author

@polarathene polarathene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL:DR:

  • The restricted workflow (docs-preview-prepare.yml) only has contents: read granted. As there is no secrets, it should roughly mirror the pull_request workflow environment security wise?
  • Confirmed memory dump for accessing the GH token, provided PR author can run shell commands on the host.

While I'm fine to take a different approach than this PR proposes, I would greatly appreciate confirmation on pull_request_target + workflow_call (as has been implemented here) as being secure, akin to a pull_request event triggered for PRs from forks.

AFAIK with the proposed approach, the PR author has even less flexibility for an attack than they would with pull_request.

# CAUTION: This runs a build script which the PR could modify for malicious purposes.
prepare:
needs: [create-context]
uses: docker-mailserver/docker-mailserver/.github/workflows/docs-preview-prepare.yml@master
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job is running untrusted code in the context of pull_request_target. There are no secrets shared with the job and only Pull Request write permissions so the risk is low,

It should only have contents: read permission. I know that it inherits from this pull_request_target permissions which have been limited, but the prepare workflow_call itself is restricted to only contents: read, pull_requests: write is for the separate deploy workflow_call.

The calling workflow docs-preview.yml / pull_request_target must grant these permissions as the sub-workflows called can only reduce the permissions scope, not add extra permissions.

Unfortunately docs-preview-prepare.yml cannot enforce secrets: none, so there is potential risk there should a maintainer call the workflow with secrets: inherit or pass a secret through.


Cant this be moved to a pull_request workflow?

That's what it was before this PR.

  • This PR has 3 workflow files, but is run as a single workflow run.
  • The approach prior to this is pull_request + workflow_run, two separate workflow files, but also treated as two separate workflow runs on the actions tab, and that complicates the management a bit with PR context + commit status management.

If we change back to pull_request, I need to run the deploy job with access to secrets and the PR metadata (the number to write the PR comment with preview link). Originally as you know we had a vulnerability there with how the PR metadata as passed via artifact and loaded into ENV, so there is still potential risk.

Comment on lines +36 to +38
# Prevent `secrets.GITHUB_TOKEN` from being stored in a `.git/config` file, which could otherwise
# be compromised when executing untrusted code from a PR (as is done in the build step below).
persist-credentials: false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token is available to an attacker by dumping the runner memory

Are you saying that persist-credentials: false is not worthwhile then?

EDIT: I have dumped memory as explained in the linked article and can confirm if those commands can be run then it's possible to get the GH token that way too 👍


you need to assume that the attacker will be able to get Pull Request write permissions

I don't understand how the attacker would get these permissions. pull_request_target does have those permissions, but this prepare job that calls the docs-preview-prepare.yml workflow is via a separate runner instance and has permissions set to only contents: read.

So while it is grouped under the same workflow run ID it should not have the calling workflow (docs-preview.yml) token in memory? Was this a misunderstanding during your review?


The safest approach is to run all untrusted code in a pull_request triggered workflow and pass any needed information to a workflow_run privileged workflow but verifying this information to make sure its the expected one.

I don't mind taking that approach, and I do agree with you that pull_request + workflow_run is the approach I would generally advise anyone else due to the risks of pull_request_target, but I would appreciate clarification on what I've done with this PR that does not mirror the equivalent pull_request environment for running docs-preview-prepare.yml?

The default permissions for pull_request when the PR is from a fork, to my knowledge is read for all scopes, while secrets is none? Have I not secured docs-preview-prepare.yml in the same way by restricting permissions and secrets via this separate workflow_call workflow?

Is there something else that pull_request does differently to be more secure?


With pull_request_target the PR author cannot modify the workflow that is run, unlike pull_request.

Presently that benefit isn't relevant due to build-docs.sh, but otherwise the build process would be sandboxed within the Docker container used, thus even if the build process was manipulated (eg: compromise via Docker image or it's dependencies), it is very unlikely an attack could then affect something on the Docker host (runner) provided our only interaction with the build output is via artifact upload/download of the build directory.

@polarathene
Copy link
Member Author

polarathene commented Nov 18, 2024

UPDATE: #4267


As another alternative (Solution 4). I have recently documented gh pr view to acquire the PR number and head SHA, and verified that it should not pose any rate limit risk.

This would be for pull_request + workflow_run, with this step added to the workflow_run:

# Minimum read permissions needed for `gh pr view`:
permissions:
  pull-requests: read
  contents: read

jobs:
# ...
  steps:
      - name: 'Get PR context'
        id: pr-context
        env:
          # Token required for GH CLI:
          GH_TOKEN: ${{ github.token }}
          # Best practice for scripts is to reference via ENV at runtime. Avoid using the expression syntax in the script content directly:
          PR_TARGET_REPO: ${{ github.repository }}
          # If the PR is from a fork, prefix it with `<owner-login>:`, otherwise only the PR branch name is relevant:
          PR_BRANCH: |-
            ${{
              (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login)
                && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch)
                || github.event.workflow_run.head_branch
            }}
        # Use GH CLI to query the PR branch for the PR number and assign it to the steps output:
        # (`--jq` formats JSON to `key=value` pairs and renames `headRefOid` to `head-sha`)
        run: |
          gh pr view --repo "${PR_TARGET_REPO}" "${PR_BRANCH}" \
            --json 'number,headRefOid' \
            --jq '"number=\(.number)\nhead-sha=\(.headRefOid)"' \
            >> $GITHUB_OUTPUT

This then provides the PR context via outputs ${{ steps.pr-context.outputs.number }} and ${{ steps.pr-context.outputs.head-sha }} for later steps/jobs to use.

@pwntester
Copy link

recently documented gh pr view

I think this is the safest approach. Unfortunately using pull_request_target is very dangerous and even if you set permissions: {}, executing untrusted code still opens the door to Cache Poisoning attacks since the code is executed in the context of the default branch and the Cache Token available has write permissions. Any untrusted code should be run only on pull_request trigger as solution 4 or the original workflow was using. Using gh pr view seems a great way to pass the PR SHA and number to the workflow_run. Using an artifact as you were doing at the beginning is also ok as long as the contents of the artifact are unzipped to /tmp and contents verified to be a number or sha.

@polarathene
Copy link
Member Author

Unfortunately using pull_request_target is very dangerous and even if you set permissions: {}, executing untrusted code still opens the door to Cache Poisoning attacks since the code is executed in the context of the default branch and the Cache Token available has write permissions.

Thanks for pointing this out! I had read similar caution from the GHA docs on pull_request_target event workflow trigger, but didn't realize that the cache could still be uploaded by an attacker. It makes sense though, given it's probably not unlike the situation with uploading artifacts 😅

A little unfortunate perhaps that we cannot opt-out of these attack vectors when we do not need the workflow to support that functionality.

Technically if my concern with build-docs.sh was addressed to limit the untrusted code to the Docker container, I don't think the attacker would have an injection point to leverage?


Using an artifact as you were doing at the beginning is also ok as long as the contents of the artifact are unzipped to /tmp and contents verified to be a number or sha.

Any specific reason for the /tmp extraction location?

Validating a PR number or SHA hash value are simple enough (I documented those here under "Solution A"), but gets a bit more complicated when the values aren't as simple to validate, and that validation alone does not ensure they're the expected values 🤔

Since these specific values can be reliably sourced via gh pr view without the PR author manipulating them I'll favor that.


I'd really like to express my gratitude for your feedback and insights shared here. The articles you've linked are fantastic at demonstrating the dangers of pull_request_target with untrusted code that are far less apparent to maintainers 😬

While I do prefer this pull_request_target + workflow_call approach, and isolating untrusted code to only run within the Docker container should be reasonably safe... I am no longer comfortable with the risks from unknowns, especially when that could affect our users.

I will move forward with Solution B (gh pr view). I've updated the linked reference to heavily discourage Solution C (pull_request_target), citing the resources you've provided.

@polarathene
Copy link
Member Author

polarathene commented Nov 20, 2024

Closing in favor of #4267

Thank you so much @pwntester for your feedback! ❤️ I almost made an even bigger mistake here with pull_request_target😬

If you engage with future projects, or someone from GHSL decides to write up another article on how to approach this workflow securely, I hope this reference I've pieced together can be helpful. It's the best I can do to give back :)

@pwntester
Copy link

If you engage with future projects, or someone from GHSL decides to write up another article on how to approach this workflow securely, I hope #4267 (comment) I've pieced together can be helpful. It's the best I can do to give back :)

Great write-up! Im planning a blog post about common pitfalls and the missing validations of artifacts in workflow_run is one of them. As the PR number is not available to workflow_run many people pass it via artifacts and do not validate its contents. Will mention your approach of using gh pr view as a safer alternative and will also raise this missing info in the workflow_run event to the internal actions teams to try to get it added to the event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.