-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[workflows] Split pr-code-format into two parts to make it more secure #78216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
147c1d2
cd37e90
8ab4b7d
1b98494
c375d8f
6bd48ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
name: Comment on an issue | ||
|
||
on: | ||
workflow_run: | ||
workflows: ["Check code formatting"] | ||
types: | ||
- completed | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
pr-comment: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
pull-requests: write | ||
if: > | ||
github.event.workflow_run.event == 'pull_request' | ||
steps: | ||
- name: 'Download artifact' | ||
# v7.0.1 | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea | ||
with: | ||
script: | | ||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
run_id: context.payload.workflow_run.id, | ||
}); | ||
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { | ||
return artifact.name == "workflow-args" | ||
})[0]; | ||
let download = await github.rest.actions.downloadArtifact({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
artifact_id: matchArtifact.id, | ||
archive_format: 'zip', | ||
}); | ||
let fs = require('fs'); | ||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/workflow-args.zip`, Buffer.from(download.data)); | ||
- run: unzip workflow-args.zip | ||
|
||
- name: 'Comment on PR' | ||
uses: actions/github-script@v3 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
script: | | ||
var fs = require('fs'); | ||
const comments = JSON.parse(fs.readFileSync('./comments')); | ||
if (!comments) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we handle errors from reading the json here and print the problems? so that we can debug that later if something goes wrong? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a step to always dump the comment file (pass or fail) at the end of the job. |
||
return; | ||
} | ||
let runInfo = await github.actions.getWorkflowRun({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
run_id: context.payload.workflow_run.id | ||
}); | ||
if (runInfo.data.pull_requests.length != 1) { | ||
console.log("Error retrieving pull request number"); | ||
console.log(runInfo); | ||
return; | ||
} | ||
const prNumber = runInfo.data.pull_requests[0].number; | ||
await comments.forEach(function (comment) { | ||
if (comment.id) { | ||
github.issues.updateComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: prNumber, | ||
comment_id: comment.id, | ||
body: comment.body | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure input validation is that necessary here, but this change means that the JSON artifact sent over should be completely untrusted as anyone can theoretically modify the workflow and make it send whatever. I don't think this should happen much in practice (depending upon the settings for whether or not new contributors need approval for workflow runs), but it theoretically gives the ability for anyone to post a comment on any PR/Issue under the Github moniker. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was able to figure out how to get the PR number from the event payload, so that will prevent someone from posting a comment on any issue in the project. So now the only untrusted inputs are the comment id and the comment body. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should ensure that the provided commit_id was previously created by this script, rather than a random other user's comment? |
||
}); | ||
} else { | ||
github.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: prNumber, | ||
body: comment.body | ||
}); | ||
} | ||
}); | ||
- name: Dump comments file | ||
if: always() | ||
run: cat comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think i you use the newer upload-artifacts and download-artifacts packages, then you don't need to deal with all the listing/downloading/unzip code -- it'll do it for you just based on a name and run_id.