SEC-004: Sanitize body content in update_handler_factory before GitHub API writes#19538
Merged
SEC-004: Sanitize body content in update_handler_factory before GitHub API writes#19538
Conversation
…date Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix body field sanitization in update_handler_factory
SEC-004: Sanitize body content in update_handler_factory before GitHub API writes
Mar 4, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Implements SEC-004 safe-outputs conformance by sanitizing free-form body content (_rawBody) inside update_handler_factory before any GitHub API update call.
Changes:
- Sanitize
updateData._rawBodyviasanitizeContent()prior to callingexecuteUpdate(...). - Add a unit test asserting that
_rawBodycontent is sanitized (specifically,@mentions are neutralized) before being forwarded toexecuteUpdate.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| actions/setup/js/update_handler_factory.cjs | Imports and applies sanitizeContent to _rawBody before GitHub API writes. |
| actions/setup/js/update_handler_factory.test.cjs | Adds a test validating that sanitized _rawBody is passed to executeUpdate. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
update_handler_factory.cjswas forwarding_rawBodydirectly toexecuteUpdatewithout sanitization, violating the Safe Outputs conformance requirement that any handler accepting free-form body/content fields MUST sanitize before writing to GitHub.Changes
update_handler_factory.cjs: ImportsanitizeContentfromsanitize_content.cjsand apply it toupdateData._rawBodybeforeexecuteUpdateis called — covers both live and staged-mode paths since sanitization happens prior to the staged check.update_handler_factory.test.cjs: Add test asserting that@mentions in body content are neutralized (e.g.@bot-trigger→`@bot-trigger`) before being passed toexecuteUpdate.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
https://api.github.com/graphql/usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE 64/pkg/tool/linux_amd64/link git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/link /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git(http block)https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --get remote.origin.url /usr/bin/git /tmp/go-build210git -trimpath 64/bin/go git conf�� user.email test@example.com /usr/bin/git -json GO111MODULE x_amd64/vet git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v3/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -bool -buildtags 414348/b397/vet.cfg -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linu^remote\..*\.gh-resolved$ -ato�� -bool l /usr/bin/gh -errorsas -ifaceassert -nilfunc gh(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v5/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha _.a GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env xYUo5Pmbz cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git -json cfg 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git 143/001/stabilitgit cfg ache/go/1.25.0/x--show-toplevel git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v6/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --get remote.origin.url cfg k/gh-aw/gh-aw/scgit GOPROXY 64/bin/go git conf�� user.email test@example.com /usr/bin/git /tmp/go-build210git -trimpath 64/bin/go git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha /tmp/gh-aw-test-runs/20260304-080555-34019/test-1728343999 rev-parse cfg pkg/mod/github.cgit GOPROXY 64/bin/go git conf�� --get remote.origin.url ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /tmp/go-build210git -trimpath At,event,headBra--show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linu--json /usr/bin/git -json cfg 64/pkg/tool/linu--show-toplevel git(http block)https://api.github.com/repos/actions/download-artifact/git/ref/tags/v8/usr/bin/gh gh api /repos/actions/download-artifact/git/ref/tags/v8 --jq .object.sha 143/001/stability-test.md GO111MODULE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/download-artifact/git/ref/tags/v8 --jq .object.sha 0555-34019/test-1927054383 GO111MODULE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet rtcf�� -json tmain.go ache/go/1.25.0/x64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/link(http block)/usr/bin/gh gh api /repos/actions/download-artifact/git/ref/tags/v8 --jq .object.sha -json GO111MODULE(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v8/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha 43Mi/COIMEuM4xQIGOSUMDB GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 386035/b404/impo-buildtags -c k/gh-aw/gh-aw/pk-errorsas k/gh-aw/gh-aw/pk-ifaceassert 64/bin/go GOSUMDB GOWORK 64/bin/go /opt/hostedtoolc-buildtags(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha prettier --check 64/bin/go **/*.ts **/*.json --ignore-path go env -json GOMOD 64/bin/go tierignore grep 64/bin/go go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha "prettier" --check '**/*.cjs' '*GOINSECURE GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go git cat-�� blob 711f56918db45f6657bdf424e5eda89fGOMOD 64/bin/go -d grep 64/bin/go go(http block)https://api.github.com/repos/actions/setup-go/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel 386035/b357/impo-buildtags ache/node/24.13.1/x64/bin/node k/gh-aw/gh-aw/ingit GOPROXY 64/bin/go git t-78�� k/gh-aw/gh-aw/.github/workflows/bot-detection.md /opt/hostedtoolc/tmp/go-build387414348/b263/vet.cfg /usr/bin/git erignore node 64/bin/go git(http block)https://api.github.com/repos/actions/setup-node/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha /tmp/gh-aw-test-runs/20260304-080555-34019/test-3574285426 config /usr/bin/git remote.origin.urgit GOPROXY 64/bin/go git rev-�� --show-toplevel /opt/hostedtoolc-buildtags e/git /tmp/go-build210git -trimpath 64/bin/go e/git(http block)https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --porcelain GOPROXY /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOSUMDB GOWORK 64/bin/go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build387414348/b082/vet.cfg 414348/b378/vet.cfg -json GO111MODULE 64/bin/go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v7/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha xYUo5Pmbz cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env ternal/tools/generate-action-metadata/main.go GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v7 --jq .object.sha -json cfg x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts/usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json cfg x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts/usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts/usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts/usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts/usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/pkg/tool/linu-nolocalimports GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/tmp/go-build387414348/b419/_testmain.go env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts/usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts/usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/actions/workflows/usr/bin/gh gh workflow list --json name,state,path data/action_pins.json..." GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 386035/b403/impo-buildtags /hom�� che/go-build/92/-errorsas **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti-bool /opt/hostedtoolc-buildtags(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 --ignore-path ../../../.pretti-bool go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE At,event,headBranch,headSha,displayTitle GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha "prettier" --check 'scripts/**/*GOINSECURE node 64/bin/go tierignore --write 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha "prettier" --check 'scripts/**/*GOINSECURE node 64/bin/go tierignore --write 64/bin/go go env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha --check scripts/**/*.js 64/bin/go .prettierignore grep 64/bin/go go env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha "prettier" --check 'scripts/**/*GOINSECURE node 64/bin/go tierignore --write 64/bin/go go env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha y-test.md GO111MODULE 64/pkg/tool/linu-nolocalimports GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/tmp/go-build387414348/b424/_testmain.go env 1258614037/.github/workflows cfg x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet(http block)https://api.github.com/repos/nonexistent/repo/actions/runs/12345/usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet(http block)https://api.github.com/repos/owner/repo/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE npx pret�� --check scripts/**/*.js 64/bin/go .prettierignore GOWORK 64/bin/go go(http block)/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE node /opt�� prettier --check 64/bin/go --ignore-path .prettierignore 64/bin/go go(http block)https://api.github.com/repos/owner/repo/contents/file.md/tmp/go-build387414348/b383/cli.test /tmp/go-build387414348/b383/cli.test -test.testlogfile=/tmp/go-build387414348/b383/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE 386035/b355/impo/tmp/go-build387414348/b144/vet.cfg -c k/gh-aw/gh-aw/cmgo1.25.0 GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go /opt/hostedtoolc-buildtags(http block)https://api.github.com/repos/test-owner/test-repo/actions/secrets/usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name Z2W9/vaMXa9K3kKT-errorsas GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 386035/b395/impo-buildtags /hom�� che/go-build/b7/-errorsas **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti-bool /opt/hostedtoolc-buildtags(http block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.