fix: various security fixes (#38406)

Addresses a batch of privately reported security issues, grouped by
area:

- **SSRF** - migration PR-patch/asset fetches, OAuth2 avatar & OpenID
discovery, pull-mirror URL re-validation, and the outbound proxy path.
- **Access-token scope** - prevent scope escalation on token creation;
keep public-only tokens confined (feeds, packages, Actions listings,
star/watch lists, limited/private owners).
- **Access control / disclosure** - go-get default-branch leak, webhook
authorization-header leak, watch clearing on private transitions,
label/attachment scoping.
- **Denial of service** - input bounds for npm dist-tags, Debian control
files, Arch file lists, and SSH keys.

### 📌 Attention for site admins

Not breaking - existing configs keep working - but two changes are worth
a look:

- **New SSRF protection** Outbound requests (migrations, OAuth2 avatars,
OpenID discovery, pull mirrors, proxy path) are now validated against
the allow/block host lists. If your instance legitimately reaches
internal hosts, you may need to add them to
`[security].ALLOWED_HOST_LIST` (and the relevant `ALLOW_LOCALNETWORKS`
settings).
- **Deprecation** `[webhook].ALLOWED_HOST_LIST` is deprecated and will
be removed in a future release. Use `[security].ALLOWED_HOST_LIST`
instead; the old key still works for now.

---------

Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
This commit is contained in:
bircni
2026-07-12 19:14:09 +02:00
committed by GitHub
parent d2bd1589fe
commit f69e15afe7
93 changed files with 1715 additions and 138 deletions
+3 -1
View File
@@ -73,7 +73,9 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
}
if publicOnly {
if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {
// a public-only token must not reach limited-visibility owners either,
// matching how orgs/users are enforced elsewhere in this file
if ctx.Package != nil && !ctx.Package.Owner.Visibility.IsPublic() {
ctx.HTTPError(http.StatusForbidden, "reqToken", "token scope is limited to public packages")
return
}
+8 -1
View File
@@ -333,11 +333,18 @@ func ListPackageTags(ctx *context.Context) {
func AddPackageTag(ctx *context.Context) {
packageName := packageNameFromParams(ctx)
body, err := io.ReadAll(ctx.Req.Body)
// the dist-tag body is only a quoted version string; bound it to avoid an unbounded
// read that could exhaust memory
const maxDistTagBodySize = 4 * 1024
body, err := io.ReadAll(io.LimitReader(ctx.Req.Body, maxDistTagBodySize+1))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
if len(body) > maxDistTagBodySize {
apiError(ctx, http.StatusRequestEntityTooLarge, errors.New("request body too large"))
return
}
version := strings.Trim(string(body), "\"") // is as "version" in the body
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName, version)