fix(security): backport upstream v1.26.2 security fixes #226

Merged
jmiller merged 6 commits from fix/225-security-backports into dev 2026-05-26 22:05:14 +00:00
Owner

Summary

Cherry-picks security and bug fixes from upstream Gitea v1.26.2 that were not included in our previous merge.

Included fixes (6 commits):

  • fix(actions): wrong assumption that run id always >= job id (#37737) -- prevents action run ordering bugs
  • fix(auth): set User-Agent on avatar fetch and sync avatar on link-account register (#37564) -- auth hardening
  • fix: make clone URL respect public URL detection setting (#37615) -- URL correctness
  • Fix basic auth bug (#37503) -- basic auth scope was not properly set for OAuth tokens
  • fix(git): Fix smart http request scope bug (#37583) -- token scope not enforced on git smart HTTP
  • chore(deps): bump go-git/go-git/v5 to 5.19.0 -- security fix in go-git dependency

Skipped (already applied from earlier merge):

OAuth PKCE, token scope enforcement, URL sanitization, CSP, permissions, mermaid, actions panics, branch protection order, merge autodetect, maintainer edit, and 7 others.

Skipped (structural divergence, not security-critical):

  • fix(pull): handle empty PR files view (#37783) -- requires variable rename refactor
  • fix: run as root check (#37622) -- not relevant (Docker deployment)

Test plan

  • Full go build ./... passes
  • go vet passes
  • Basic auth with OAuth token works
  • Git smart HTTP clone respects token scope

Ref #225

## Summary Cherry-picks security and bug fixes from upstream Gitea v1.26.2 that were not included in our previous merge. ### Included fixes (6 commits): - **fix(actions): wrong assumption that run id always >= job id** (#37737) -- prevents action run ordering bugs - **fix(auth): set User-Agent on avatar fetch and sync avatar on link-account register** (#37564) -- auth hardening - **fix: make clone URL respect public URL detection setting** (#37615) -- URL correctness - **Fix basic auth bug** (#37503) -- basic auth scope was not properly set for OAuth tokens - **fix(git): Fix smart http request scope bug** (#37583) -- token scope not enforced on git smart HTTP - **chore(deps): bump go-git/go-git/v5 to 5.19.0** -- security fix in go-git dependency ### Skipped (already applied from earlier merge): OAuth PKCE, token scope enforcement, URL sanitization, CSP, permissions, mermaid, actions panics, branch protection order, merge autodetect, maintainer edit, and 7 others. ### Skipped (structural divergence, not security-critical): - fix(pull): handle empty PR files view (#37783) -- requires variable rename refactor - fix: run as root check (#37622) -- not relevant (Docker deployment) ## Test plan - [ ] Full go build ./... passes - [ ] go vet passes - [ ] Basic auth with OAuth token works - [ ] Git smart HTTP clone respects token scope Ref #225
jmiller added 6 commits 2026-05-26 21:55:24 +00:00
Backport #37737

Fix #37734

Follow up #37008

The `jobNum >= runNum` check is useless. Removed it to support `job_id <
run_id`
Backport #37588 by @pandareen

## Summary

Fixes
[go-gitea/gitea#37564](https://github.com/go-gitea/gitea/issues/37564):
when an OIDC provider returns a `picture` claim, Gitea is supposed to
download that image as the user's avatar (if `[oauth2_client]
UPDATE_AVATAR = true`). Two latent bugs prevented this from working
consistently:

1. **Default Go User-Agent rejected by some image hosts.**
`oauth2UpdateAvatarIfNeed` used `http.Get`, which sends `User-Agent:
Go-http-client/1.1`. Hosts like `upload.wikimedia.org` reject that UA
with `403`, and every error path silently returned, so the user was left
with an identicon and **no log line** to diagnose the issue.
2. **Link-account *register* path skipped avatar sync.** First-time OIDC
sign-ins where auto-registration is disabled (or required a
username/password retype) go through `LinkAccountPostRegister`, which
created the user but never called `oauth2SignInSync`. So the avatar /
full name / SSH keys from the IdP were dropped on the floor for those
users, even though the existing-account-link path (`oauth2LinkAccount`)
and the auto-register path (`handleOAuth2SignIn`) both already did the
sync.

## Changes

- `routers/web/auth/oauth.go` — `oauth2UpdateAvatarIfNeed` now uses
`http.NewRequest` + `http.DefaultClient.Do`, sets `User-Agent: Gitea
<version>`, and logs every failure path at `Warn` (invalid URL, fetch
error, non-200, body read error, oversize body, upload error). No silent
failures.
- `routers/web/auth/linkaccount.go` — `LinkAccountPostRegister` now
calls `oauth2SignInSync` after a successful user creation, mirroring the
auto-register and link-existing-account flows.
- `tests/integration/oauth_avatar_test.go` — new
`TestOAuth2AvatarFromPicture` integration test with five sub-cases:
- `AutoRegister_FetchesAvatarFromPictureWithGiteaUA` — happy path,
asserts `use_custom_avatar=true`, an avatar hash is set, exactly one
HTTP request was made, and the request carried a `Gitea ` UA. The mock
server enforces the UA prefix to mirror real-world hosts that reject
Go's default UA.
- `AutoRegister_NonOK_DoesNotUpdateAvatar` — server returns 403; user's
avatar must remain unset.
- `AutoRegister_EmptyPicture_NoFetch` — empty `picture` claim must not
trigger any HTTP request.
- `AutoRegister_UpdateAvatarFalse_NoFetch` — `UPDATE_AVATAR=false` must
not trigger any HTTP request.
- `LinkAccountRegister_FetchesAvatarFromPicture` — guards the
`linkaccount.go` fix; without the new `oauth2SignInSync` call this
assertion fails.

## Test plan

- [x] `go test -tags 'sqlite sqlite_unlock_notify' -run
'^TestOAuth2AvatarFromPicture$' ./tests/integration/ -v` — 5/5 sub-tests
pass.
- [x] Manual: log in as a Keycloak user with `picture` claim pointing at
`https://avatars.githubusercontent.com/u/9919?v=4` — Gitea avatar is
replaced with the GitHub picture.
- [x] Manual: same flow with `https://upload.wikimedia.org/...` —
request now succeeds (or returns a clearly logged `Warn` line if
rate-limited with `429`); previously it silently 403'd.
- [x] Manual: `UPDATE_AVATAR=false` — user keeps the identicon, no
outbound request in container logs.
- [ ] Reviewer: please double-check that no other call sites of
`oauth2UpdateAvatarIfNeed` rely on the old `http.Get` behaviour.

## Related

- Upstream issue: go-gitea/gitea#37564
--------------------------------------------


AI Editor was used in this PR

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: pandareen <7270563+pandareen@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Backport #37615 by @wxiaoguang

Fix #37614

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport for #37486
Backport #37583 by @lunny

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
chore(deps): bump go-git/go-git/v5 to 5.19.0 (security)
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
PR RC Release / Build RC Release (pull_request) Successful in 2s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Failing after 20s
775766bc64
Addresses security fixes in the go-git library. Upstream backport of
go-gitea/gitea#37608.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jmiller merged commit 360d0b1b1f into dev 2026-05-26 22:05:14 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoGitea#226