Skip to content

fix: Reject an upload URL whose host differs from the configured upload host - #4556

Merged
gmlewis merged 4 commits into
google:masterfrom
sushant-me:fix/upload-release-asset-foreign-host
Sep 17, 2026
Merged

gmlewis merged 4 commits into
google:masterfrom
sushant-me:fix/upload-release-asset-foreign-host

Conversation

@sushant-me

Copy link
Copy Markdown
Contributor

UploadReleaseAssetFromRelease takes release.UploadURL from the server's response, and NewUploadRequest lets an absolute URL replace the client's configured upload host entirely (url.URL.Parse discards the receiver for an absolute reference). A response naming a different host therefore received the artifact and the caller's Authorization header, while the caller's own WithURLs/WithEnterpriseURLs upload configuration was silently ignored.

release := &RepositoryRelease{UploadURL: "https://example.invalid/upload{?name,label}"}
// previously: POST https://example.invalid/upload?name=n.txt  (with the bearer token)
// now:        error: upload URL host "example.invalid" does not match the
//             client's configured upload host "uploads.github.com"

The check runs only for absolute values; relative URLs — what GitHub actually returns, and the case the existing tests cover — are untouched. It compares against c.uploadURL rather than c.baseURL, because uploads.github.com and github.com/ghapi differ by design.

This does not overlap with #4363/#4364/#4366: those scope the token for a foreign origin but would still POST the artifact body there. Rejecting the request keeps both on the configured host.

TestRepositoriesService_UploadReleaseAssetFromRelease_ForeignHostIsRejected fails on master (expected an error for an upload URL naming a foreign host, got nil) and passes with this change. go test ./github/ and script/lint.sh both pass.

Assisted contribution: an AI tool drafted the change, the test, and this description. I reviewed the rendered diff, ran the full github package test suite and script/lint.sh, and verified the new test fails without the fix.

@google-cla

google-cla Bot commented Sep 15, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@sushant-me

Copy link
Copy Markdown
Contributor Author

@googlebot I signed it!

UploadReleaseAssetFromRelease takes release.UploadURL from the server's
response, and NewUploadRequest lets an absolute URL replace the client's
configured upload host entirely. A response naming a different host was
therefore able to receive the artifact together with the caller's
Authorization header, while the caller's own WithEnterpriseURLs/WithURLs
configuration was silently ignored.

Resolve the value against the configured upload origin and reject a
differing host, so an upload can only go where the client was told to send
it. Relative URLs (the normal case, and what GitHub returns in practice)
are unaffected, and the comparison is against uploadURL rather than baseURL
because uploads.github.com differs from github.com/ghapi by design.
@sushant-me
sushant-me force-pushed the fix/upload-release-asset-foreign-host branch from f8441ba to cac306d Compare September 15, 2026 09:01
@gmlewis gmlewis added the NeedsReview PR is awaiting a review before merging. label Sep 15, 2026
@codecov

codecov Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.57%. Comparing base (44d6f18) to head (8590220).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4556   +/-   ##
=======================================
  Coverage   98.57%   98.57%           
=======================================
  Files         197      197           
  Lines       18291    18299    +8     
=======================================
+ Hits        18030    18038    +8     
  Misses        261      261           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gmlewis

gmlewis commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

@sushant-me - can you please increase the CodeCov results for this critical piece of code?

Exercises the url.Parse error return in UploadReleaseAssetFromRelease so
every line of the new host check is covered. A URL containing an ASCII
control character makes net/url refuse the value, and the helper must
surface that as an error rather than uploading to an unchecked host.
@sushant-me

Copy link
Copy Markdown
Contributor Author

@gmlewis done - added TestRepositoriesService_UploadReleaseAssetFromRelease_MalformedUploadURL, which exercises the url.Parse error return (a URL with an ASCII control character makes net/url refuse it). That was the uncovered line in repos_releases.go, so patch coverage should now be 100%. go test ./github/ and ./script/lint.sh both pass locally.

@gmlewis gmlewis changed the title Reject an upload URL whose host differs from the configured upload host fix: Reject an upload URL whose host differs from the configured upload host Sep 15, 2026

@gmlewis gmlewis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you, @sushant-me!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.

cc: @stevehipwell - @Not-Dhananjay-Mishra

@sushant-me

sushant-me commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the LGTM, @gmlewis! Everything is green CLA, codecov patch/project, and the full test matrix and the branch is current with master, so this is ready for a second LGTM whenever someone has bandwidth. Happy to make any adjustments if something needs changing.

Comment thread github/repos_releases.go Outdated
Comment thread github/repos_releases_test.go Outdated
Applies the wording suggestions from review on google#4556: the error message
formats both hosts with %v, and the test failure formats the leak counter
with %v rather than %d.

Verified: gofmt clean, go build ./... ok, and all nine
TestRepositoriesService_UploadReleaseAssetFromRelease subtests pass.
@sushant-me

Copy link
Copy Markdown
Contributor Author

@Not-Dhananjay-Mishra thanks for the review — both suggestions are applied in 8590220: %v for the two host verbs in the error, and %v for the leak counter in the test failure.

Re-verified locally: gofmt -l clean, go build ./... ok, and all nine TestRepositoriesService_UploadReleaseAssetFromRelease subtests pass. CI is re-running now. Happy to change anything else.

@Not-Dhananjay-Mishra Not-Dhananjay-Mishra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@gmlewis gmlewis removed the NeedsReview PR is awaiting a review before merging. label Sep 17, 2026
@gmlewis

gmlewis commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Thank you, @Not-Dhananjay-Mishra!
Merging.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants