Skip to content

← Public intelligence

Go package

code.gitea.io/gitea

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

105 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. Medium, CVSS 6.5GoPublished

    Gitea: Cross-Repo Information Disclosure via Org-Level Actions Run/Job APIs

    CVE-2026-57897 · GHSA-frpw-3h2q-4jj6

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Author: Prakhar Porwal Date: 2026-05-24 Target: Gitea (self-hosted Git service) Branch tested: main @ b7e95cc48c (development build, go1.26.3) Component: routers/api/v1/org/action.go (org-level Actions API) OWASP: API3:2023 Broken Object Property Level Authorization --- 1. Summary The org-level Actions REST endpoints are gated only by reqOrgMembership() + reqToken(). They then call shared.ListRuns(ctx, ctx.Org.Organization.ID, 0) / shared.ListJobs(ctx, ctx.Org.Organization.ID, 0, 0, nil), which selects every actionrun / actionrunjob row whose repository belongs to the org — with no per-repository ACL check. Result: any user who is a member of an organization can enumerate workflow runs and jobs from every repository in that org, including: private repositories the caller has no team membership for, repositories where the caller has been explicitly denied the repo.actions unit, repositories created by other teams the caller is not part of. Direct per-repo equivalents (GET…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  2. Medium, CVSS 4.3GoPublished

    Gitea: GHSA-8fwc-qjw5-rvgp ClearRepoWatches fix not applied to API EditRepo path — sister code path retains stale watches on public->private

    CVE-2026-58510 · GHSA-q423-49rw-g9mh

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    GHSA-8fwc-qjw5-rvgp ("Gitea may send release notification emails for private repositories to users whose access has been revoked", fix in PR #36319 / commit 8a98ac22) added repomodel.ClearRepoWatches as a defense for the state transition public→private. The cleanup was wired into services/repository/repository.go::MakeRepoPrivate only. The sister helper services/repository/repository.go::updateRepository — which is the function used by the API path PATCH /api/v1/repos/{owner}/{repo} — was not patched and still calls ClearRepoStars only. As a result, when a public repository is flipped to private via the REST API (rather than via the web Settings → Danger Zone UI), the watch records persist. Affected users can: - See the now-private repository in GET /api/v1/user/subscriptions?private=true along with its full Repository JSON (description, default branch, language, fork status, counts, mirror metadata, license list, etc.) — even though they have no access to the repository. -…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  3. High, CVSS 7.6GoPublished

    Gitea: Improper authorization on OAuth sign-in callback silently re-enables administrator-disabled accounts

    CVE-2026-58422 · GHSA-g9g6-qhrc-p3qc

    Affected
    • Go code.gitea.io/gitea < 1.26.4
    Fixed in
    1.26.4· Vendor fix available
    Issue
    The OAuth2 sign-in callback in Gitea 1.26.1 unconditionally re-enables a locally-disabled account whenever the user authenticates through a linked external identity provider, silently undoing any administrator-initiated Disable Account action and issuing a fresh authenticated session in the same response. Once a user has linked any external IdP, the administrator's disable toggle becomes non-binding — the user can re-enable themselves on demand by completing one OAuth callback, regaining full read and write access to their repositories, organizations, and access tokens. Details Improper Authorization is present on the code and state parameters of the /user/oauth2/{source-name}/callback endpoint in Gitea version 1.26.1. The handler routers/web/auth/oauth.go::handleOAuth2SignIn reads the local user's IsActive flag at lines 350-352 and, when it is false, sets opts.IsActive = optional.Some(true) before calling userservice.UpdateUser and immediately establishing a session. The…

    Recommended action: Upgrade to 1.26.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  4. High, CVSS 8.8GoPublished

    Gitea: Cached Per-Branch Permission Check in Pre-Receive Hook Allows Full Repository Write

    CVE-2026-27775 · GHSA-649p-mmhf-85c7

    Affected
    • Go code.gitea.io/gitea < 1.26.3
    Fixed in
    1.26.3· Vendor fix available
    Issue
    Vulnerability Header | Field | Value | | ------------------- | ----------------------------------------------------------------------------------- | | Vulnerability Title | Cached Per-Branch Permission Check in Pre-Receive Hook Allows Full Repository Write | | Severity Rating | High | | Bug Category | Authorization Bypass | | Location | routers/private/hookprereceive.go:55-64, CanWriteCode() | | Affected Versions | 1.25.5 | Executive Summary The pre-receive hook in Gitea evaluates the CanMaintainerWriteToBranch permission only once per git push session and caches the result for all subsequent refs in the same batch. An attacker who has a legitimate per-branch write grant (e.g., via an open pull request with "Allow edits from maintainers" enabled) can batch-push that branch together with any other ref. The cached true from the first ref is reused for all following refs, allowing the attacker to overwrite protected branches (including main), create arbitrary new branches, and push…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  5. High, CVSS 7.7GoPublished

    Gitea: Two SSRF findings

    CVE-2026-58314 · GHSA-2fcr-jfvc-vgg2

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    | --- | --- | | Versions tested | gitea/gitea:1.26.2 (digest sha256:7d13848af12645600a5f9d93ee2560daa9c6fa6b5b859b7bff3a5e1c0b661031); gitea/gitea:latest resolves to the same digest at time of writing | | Source review | git checkout v1.26.2 (commit 2c749ce) | | Reproduction | bash runpoc.sh (single shot: brings up containers, runs three PoCs, prints captured evidence, tears down on exit) | | Files touched by the fixes | modules/hostmatcher/hostmatcher.go, modules/auth/openid/openid.go | Summary Gitea guards outbound HTTP from webhooks and repo migration with net.Dialer.Control, the correct hook point. The IP classifier behind it misses ten address families, of which CGNAT (100.64.0.0/10) is the practically important one because it is plain IPv4 and is used today by Tailscale, AWS VPC secondary CIDRs, and several Kubernetes pod-CIDR conventions. Any logged-in user can create a webhook pointing at an internal CGNAT host. The full HTTP response from that host (status, headers, body up…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  6. High, CVSS 8.7GoPublished

    Gitea: ParseAcceptLanguage quadratic-time DoS via Locale middleware on unauthenticated requests

    CVE-2026-58436 · GHSA-fw57-jgch-pgf3

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    The Locale middleware that runs in front of every unauthenticated request calls golang.org/x/text/language.ParseAcceptLanguage on the raw Accept-Language header without imposing a size or shape filter. The underlying parser has quadratic-time behaviour on long lists of malformed language tags. The CVE-2022-32149 guard that golang.org/x/text added in v0.3.8 caps the number of - characters in the input at 1000, but it does not cap characters even though the parser's internal scanner aliases to - before parsing. A single unauthenticated GET request with an Accept-Language header built out of separators burns ~2 seconds of server CPU on the host running Gitea; ten concurrent attackers saturate a ten-core box for the duration of the attack while consuming ~1 MiB of upstream bandwidth per request. Affected versions code.gitea.io/gitea 1.22.6 and (per code inspection of main) all earlier and later 1.22.x / 1.23.x / 1.24.x / 1.25.x / 1.26.x versions that do not impose their own size…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  7. High, CVSS 7.1GoPublished

    Gitea: Repository Visibility Manipulation via Git Push Options

    CVE-2026-58437 · GHSA-8p9h-49rc-qgxj

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Repository Visibility Manipulation via Git Push Options | Field | Value | |-------|-------| | Affected File | routers/private/hookpostreceive.go | | Affected Function | HookPostReceive() | | Affected Lines | 173–225 | | Prerequisite | Attacker must have owner-level or admin collaborator access to the target repository | --- Description Gitea's post-receive git hook handler processes git push options — key-value pairs transmitted by a client during git push using the -o flag. Two undocumented push options, repo.private and repo.template, allow any user with repository owner or admin-collaborator access to toggle the visibility (private/public) and template status of a repository as a side effect of a normal git push. This capability was originally intended solely for the "push-to-create" feature (automatically creating a repo on first push). However, the options are processed without restriction on already-existing repositories, and — critically — the visibility change bypasses every…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  8. High, CVSS 8.1GoPublished

    Gitea: OAuth2 sign-in reactivates an administrator-deactivated account on auth sources without refresh tokens (incomplete fix of #38009)

    CVE-2026-55987 · GHSA-vrhc-jjfc-m3m3

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea's OAuth2 sign-in callback reactivates a deactivated user account (IsActive=false) when the user signs in through an authentication source that does not issue refresh tokens (notably GitHub, and any OIDC/OAuth2 source configured without offlineaccess). PR #38009 added a gate intended to reactivate users only when the OAuth2 auto-sync cron had disabled them, using "the stored refresh token is empty" as the signal. That signal is wrong: for sources that never issue refresh tokens, an empty refresh token is the normal state of every user, so the gate cannot distinguish a cron-disabled account from one an administrator deliberately deactivated. The next time the administrator-deactivated user signs in through the provider, Gitea sets IsActive=true and grants a full session, silently undoing the administrator's action. This is the exact behavior #38009 was written to prevent. (ProhibitLogin, the hard ban, is enforced separately and is not affected.) No special privileges…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  9. Medium, CVSS 5.4GoPublished

    Gitea LFS Deploy-Key Privilege Escalation

    CVE-2026-58435 · GHSA-rh79-75qm-gwjr

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Vulnerability Header | Field | Value | | ------------------- | ----------------------------------------------------------- | | Vulnerability Title | Gitea LFS Deploy-Key Privilege Escalation | | Severity Rating | High | | Bug Category | Insufficient Authorization | | Location | services/lfs/server.go:268, routers/private/serv.go:275 | | Affected Versions | 1.25.5 | Executive Summary Gitea's LFS server (services/lfs/server.go:268) uses the UserID embedded in an LFS JWT to make cross-repository authorization decisions via LFSObjectAccessible(). This would be safe if the JWT UserID always matched the actual requesting principal — but for deploy keys, routers/private/serv.go:275 sets UserID = repo.OwnerID instead of any identity representing the deploy key itself. As a result, an attacker who holds a write deploy key for any single repo owned by a victim can obtain a legitimate JWT (via the standard SSH git-lfs-authenticate flow) that Gitea will honor as if the victim themselves were…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  10. Low, CVSS 2.7GoPublished

    Gitea: Null Pointer Dereference in AddTime API Causes Authenticated Denial of Service

    CVE-2026-55984 · GHSA-m932-crvm-gcp5

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    The AddTime API handler continues execution after an error returned by GetUserByName(). When a repository administrator specifies a non-existent user name, an error response is generated but execution does not stop. Subsequent code dereferences a nil user pointer, resulting in a runtime panic. Details Affected endpoint: Affected file: Relevant code: Execution continues to: When GetUserByName() fails, user is nil. The subsequent call dereferences the nil pointer and triggers a runtime panic. Proof of Concept Using a repository administrator account: Result: The stack trace indicates execution reaches the AddTime code path with a nil user object. Impact An authenticated repository administrator can repeatedly trigger server-side panics through the affected endpoint. Depending on deployment configuration and panic recovery behavior, this may result in request failures, stack trace disclosure, excessive log generation, or degraded service availability. Suggested Fix Add a return…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  11. Medium, CVSS 5.3GoPublished

    Gitea: OIDC userinfo Endpoint Returns Identity Claims Without Enforcing API Token Scopes

    CVE-2026-55982 · GHSA-mg4f-x9v4-6h2p

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    The OIDC userinfo endpoint (GET /login/oauth/userinfo) accepts Gitea API tokens as bearer credentials but does not enforce API token scopes before returning identity claims. A personal access token scoped only to read:misc can successfully retrieve user information from the OIDC userinfo endpoint, even though the same token is denied access to user-related REST API endpoints that enforce scope checks. As a result, identity information remains accessible through the OIDC endpoint regardless of the scopes assigned to the API token. Details Gitea supports scoped personal access tokens and enforces scope checks on user-related REST API endpoints. For example, a token scoped only to read:misc is denied access to endpoints such as: | Endpoint | Required Scope | |----------|----------------| | GET /api/v1/user | read:user | | GET /api/v1/user/emails | read:user | | GET /api/v1/user/orgs | read:organization | Requests to these endpoints return: with a scope-related error. However,…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  12. Low, CVSS 2.3GoPublished

    Gitea: Private Repository Metadata Remains Accessible After Access Revocation

    CVE-2026-58434 · GHSA-j2w3-9c3r-g83q

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    A user who previously had access to a private repository can continue to obtain repository metadata through GET /api/v1/user/starred after their access to the repository has been revoked. After a collaborator is removed from a private repository, direct access to the repository is correctly denied. However, the repository may still appear in the user's starred repository list, and the endpoint continues to return repository metadata. Changes made to that metadata after access revocation are also reflected in subsequent responses. Details The issue affects the authenticated endpoint: The same behavior was also observed on: A reproducible scenario is: 1. User alice creates a private repository. 2. User bob is granted collaborator access. 3. bob stars the repository. 4. alice removes bob from the repository collaborators. 5. Direct repository access by bob is denied. 6. bob requests /api/v1/user/starred. 7. The repository is still present in the response together with repository…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  13. High, CVSS 7.5GoPublished

    Gitea: Internal API HTTP client hardcodes InsecureSkipVerify:true with no config override

    CVE-2026-54481 · GHSA-94v3-77j7-vm48

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea's internal API HTTP client (modules/private/internal.go) hardcodes TLSClientConfig.InsecureSkipVerify = true with no configuration override. It is the only outbound TLS client in the codebase that cannot be made to verify its peer's certificate — webhook, migrations, MinIO, LDAP, SMTP, Redis and incoming-mail all expose a secure-by-default SkipVerify toggle, this one does not. When an operator configures internal communication over HTTPS to a non-loopback target (LOCALROOTURL=https://<host/ in a split-host / multi-pod topology), the gitea serv / gitea hook subprocess that calls the internal API will accept ANY TLS certificate. An attacker with on-path position on that internal segment can MITM the connection and capture the static high-privilege INTERNALTOKEN, which is the sole authentication for every /api/internal/ endpoint (server shutdown/restart, SSH key authorization, git command execution, repo hooks, mail send, runner-token generation). Severity is…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  14. Medium, CVSS 4.3GoPublished

    Gitea: RSS/Atom feed handlers bypass API-token scope & public-only confinement (incomplete fix of #37698)

    CVE-2026-50105 · GHSA-6cqf-375w-639g

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea's RSS/Atom feed handlers accept API-token Basic auth but perform no token-scope or public-only enforcement. A personal access token that is correctly blocked (HTTP 403) from a private repository on /raw, /media, /archive, and /releases/download/... — because it is marked public-only or lacks the repository scope category — still returns that repository's private content through the feed routes. This is a token-confinement bypass and appears to be an incomplete fix of #37698, which added that scope enforcement to the download handlers but not to the sibling feed handlers. This is not a cross-user access bug: the requesting account must still legitimately have repo read access (RepoAssignment + reqUnitCodeReader are enforced). What is bypassed is the guarantee that a confined token cannot reach private content — which is exactly the property #37698 was shipped to provide for downloads, and which matters when such a token is handed to a third-party service/CI, leaked, or…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  15. Medium, CVSS 6.5GoPublished

    Gitea: Denial of Service via Unbounded io.ReadAll in NPM Package Tag Endpoint

    CVE-2026-42931 · GHSA-wwqq-x6w4-frm2

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    An unbounded io.ReadAll(ctx.Req.Body) call in the NPM package tag API endpoint allows any authenticated user to crash the Gitea server by sending a single large HTTP request. The request body is read entirely into memory with no size limit, causing an Out-of-Memory (OOM) kill. With concurrent requests, the attack produces a persistent denial of service that survives automatic restarts. Details The AddPackageTag function reads the entire HTTP request body into memory using io.ReadAll() with no size validation: This route is registered at routers/api/packages/api.go:433: Why this causes OOM and not just a slow request: In Go, io.ReadAll() reads into a []byte that grows dynamically. When the incoming data exceeds available memory, the Go runtime attempts to allocate a larger backing array. This allocation fails, triggering an unrecoverable runtime.throw("out of memory") that kills the entire process, not just the goroutine handling the request. No server-side size limits apply…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  16. Low, CVSS 2.7GoPublished

    Gitea: Cross-repository label-ID enumeration oracle via unscoped DeleteIssueLabel API

    CVE-2026-58445 · GHSA-pgqf-926r-548m

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    The API endpoint DELETE /repos/{owner}/{repo}/issues/{index}/labels/{id} loads the label by ID with a global, unscoped lookup and never verifies the label belongs to the URL's repository (or its owning organization). Because the response status differs by whether the label ID exists anywhere on the instance (204) versus not (422), an authenticated user can use the endpoint as a cross-repository label-ID existence / enumeration oracle, including for labels in repositories and organizations they cannot access. Severity - The leaked information is minimal (existence/count of label IDs instance-wide); no label name, color, or owning repository is disclosed, and no cross-repository write occurs. Affected / patched versions - Affected: through 1.26.3 (latest at time of report). - Patched: none yet. Details DeleteIssueLabel resolves the label with a global loader and never checks its scope: GetLabelByID (models/issues/label.go) is e.ID(labelID).Get(l) with no repoid / orgid filter.…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  17. Medium, CVSS 4.3GoPublished

    Gitea: Personal access token scope enforcement bypass on the repository home page (GET /{owner}/{repo}) discloses private repository contents

    CVE-2026-58444 · GHSA-cp3q-vrj2-ghhh

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    A personal access token (PAT) or OAuth2 token that does not carry the repository scope or that is public-only is correctly rejected (HTTP 403) by the recently hardened web content routes (archive download, raw/media file download, and repository RSS/Atom feeds). However, the repository home page route GET /{owner}/{repo} (handler repo.Home) serves the private repository's rendered README, root file/directory tree, description, language statistics, license, and latest-release information to that same token. This is a token-scope enforcement bypass and private-repository content disclosure. It is the same source→sink pattern already fixed for neighbouring routes in: - GHSA-cr4g-f395-h25h (CVE-2026-20706) token scope bypass on web archive download - GHSA-3pww-vcvm-3gmj (CVE-2026-27761) token scope bypass on repository RSS/Atom feeds repo.Home is the remaining token-auth-enabled content route that was not given the guard. Details / Root cause Web routes accept token…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  18. Critical, CVSS 9.6GoPublished

    Gitea: Public-only repository tokens can update private PR head branches

    CVE-2026-58443 · GHSA-xxjv-752h-3vp2

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea allows a public-only,write:repository token to update a private pull request head branch through a public base repository route. The vulnerable endpoint is: Gitea checks the token's public-only restriction against the route repository, which is the public base repository. UpdatePullRequest() then authorizes the pull request head repository with ordinary user RBAC and calls the pull update service. If the head repository is private, the active token's public-only restriction is not re-applied to that private repository before Gitea pushes changes into it. As a result, the same token that cannot directly write to the private repository can still cause Gitea to push public base commits into the private head branch. Details The pull request API routes are attached under a repository route group. The public-only check applies to ctx.Repo.Repository, the route/base repository. For POST /api/v1/repos/{public-owner}/{public-repo}/pulls/{index}/update, the route repository can…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  19. Medium, CVSS 6.5GoPublished

    Gitea: Repository migration SSRF via multi-answer DNS allow-list bypass

    CVE-2026-58442 · GHSA-h2x6-g7q6-344v

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea's repository migration URL validation can be bypassed when a migration hostname resolves to multiple IP addresses. The validation logic accepts the destination if any resolved IP is allowed, even if another resolved IP is loopback, private, or otherwise blocked. The later git clone operation resolves the hostname again outside of that validation decision, so it can connect to the internal address. An authenticated low-privilege user who can create repository migrations can use an attacker-controlled DNS name to make Gitea connect to internal-only Git services and import their contents into a repository controlled by the attacker. Details The issue is in services/migrations/migrate.go, in the migration allow/block-list check. Current logic computes whether any resolved IP is allowed: Then, when an allow-list is active, the host is accepted if the hostname matches or ipAllowed is true: This means a hostname resolving to both: - an allowed public IP, e.g. 1.2.3.4 - a…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  20. Medium, CVSS 6.3GoPublished

    Gitea: SSRF in restore-repo via unsanitized pull_request.yml Head.CloneURL

    CVE-2026-58441 · GHSA-xmj7-xj85-hfc3

    Affected
    • Go code.gitea.io/gitea < 1.27.0
    Fixed in
    1.27.0· Vendor fix available
    Issue
    Gitea's restore-repo CLI command restores a repository from a dump directory/archive. When parsing pullrequest.yml from that dump, the Head.CloneURL field is used to add a git remote and fetch from it with no validation, because the safety check that's supposed to guard it (CheckAndEnsureSafePR) is called with an empty commonCloneBaseURL, which silently disables it. This lets a malicious dump make the Gitea server execute git fetch against an attacker-chosen URL (SSRF), or disclose a local git repository via file://. This is a different root cause from the recently fixed path-traversal issue in the same command (#38215), which patched DownloadURL/PatchURL but not Head.CloneURL. Details services/migrations/restore.go's GetPullRequests() unmarshals pullrequest.yml directly into base.PullRequest structs with no validation of Head.CloneURL: CheckAndEnsureSafePR (services/migrations/common.go) is supposed to reject Head.CloneURL/PatchURL values that don't share a common base URL:…

    Recommended action: Upgrade to 1.27.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  21. High, CVSS 8.9GoPublished

    Gitea: Permanent Fork PR Workflow Approval Gate Bypass

    CVE-2026-58424 · GHSA-777r-4v59-6486

    Affected
    • Go code.gitea.io/gitea < 1.26.3
    Fixed in
    1.26.3· Vendor fix available
    Issue
    | Field | Value | |-------|-------| | Identifier (researcher-assigned) | GITEA-2026-004 | | Product | Gitea (self-hosted Git service) | | Component | Gitea Actions — fork pull request approval gate | | Affected versions | All Gitea releases v1.20.0 and later, including the latest main (1.27.0+dev-289-gb7e95cc48c). The buggy logic was introduced in commit edf98a2dc3 — "Require approval to run actions for fork pull request (#22803)", 2023-02-24 — and has shipped unchanged since. | | Fixed in | not yet (this disclosure) | | Authentication required | Yes — one unprivileged Gitea account capable of forking the target repository (the default ability for every authenticated user) | | User interaction required | Exactly once — a repository administrator must approve a single benign fork PR's workflow run from the attacker. After that, no further interaction is ever required for any future fork PR from the same attacker on the same repository. | | Discovered by | Prakhar Porwal —…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  22. High, CVSS 7.7GoPublished

    Gitea: LFS authentication bypass via malformed SSH sub-verb allows unauthorized read access to private repositories

    CVE-2026-58423 · GHSA-7wvc-rvp7-w99x

    Affected
    • Go code.gitea.io/gitea >= 1.23.0, < 1.26.3
    Fixed in
    1.26.3· Vendor fix available
    Issue
    A flaw in SSH LFS sub-verb handling allows any authenticated SSH user to obtain valid LFS credentials for any repository on the instance, including private repositories they have no access to. This enables unauthorized download of all LFS objects from any private repository. Details In cmd/serv.go, the getAccessMode function determines the required access level for SSH operations. For LFS verbs (git-lfs-authenticate, git-lfs-transfer), it switches on the sub-verb (upload/download). If the sub-verb is neither, execution falls through to: In production (IsProd=true), PanicInDevOrTesting only logs an error and does not panic. AccessModeNone (value 0) is then passed to ServCommand in routers/private/serv.go, where the permission check block at line ~322 evaluates: For private repositories, repo.IsPrivate triggers the permission check block, but userMode < mode evaluates to userMode < 0, which is always false — access is granted regardless of the user's actual permissions. The…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  23. Medium, CVSS 4.3GoPublished

    Gitea: API access token scope enforcement bypass on repository RSS/Atom feed endpoints leaks private repository commit data

    CVE-2026-27761 · GHSA-3pww-vcvm-3gmj

    Affected
    • Go code.gitea.io/gitea <= 1.26.2
    Fixed in
    1.26.3· Vendor fix available
    Issue
    A Gitea personal access token (PAT) restricted to a non-repository scope (e.g. read:issue) can read the commit history of any private repository the token owner can access, via the repository RSS/Atom feed endpoints. The same token is correctly denied (403) on /raw, /media, /archive, and the contents API. It leaks commit SHAs, full commit messages (which frequently contain secrets and internal context), and committer name + email. Details Gitea enforces PAT scope on repository-content endpoints via checkDownloadTokenScope() (added in PR #37698, extended to the archive endpoint by the CVE-2026-20706 fix in 1.26.2). The RSS/Atom feed handlers were never included: they (a) opt into PAT auth via webAuth.AllowBasic, (b) serve private-repo content, but (c) never call checkDownloadTokenScope(). Affected handlers (all carry AllowBasic, none call the scope check): - RenderBranchFeedRSS/Atom - routers/web/feed/render.go (last 10 commits: SHA, title, full message, committer name +…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  24. Critical, CVSS 9.8GoPublished

    Gitea Docker image: REVERSE_PROXY_TRUSTED_PROXIES = * default lets any source IP impersonate any user via X-WEBAUTH-USER

    CVE-2026-20896 · GHSA-f75j-4cw6-rmx4

    Affected
    • Go code.gitea.io/gitea < 1.26.3
    Fixed in
    1.26.3· Vendor fix available
    Issue
    The Gitea Docker images ship an app.ini template that hard-codes: The documented default for this setting, in custom/conf/app.example.ini, is 127.0.0.0/8,::1/128, i.e. only loopback is trusted. When an admin enables ENABLEREVERSEPROXYAUTHENTICATION = true to put Gitea behind an authenticating reverse proxy and leaves the trusted-proxies setting at "the default", they expect only the proxy's loopback connection to inject identity. The Docker image instead trusts X-WEBAUTH-USER from any source IP that can reach the container. Affected - gitea/gitea Docker images (verified 1.26.2) - docker/root/etc/templates/app.ini:55 - docker/rootless/etc/templates/app.ini:52 Binary distribution and self-built deployments that follow app.example.ini get the loopback-only default and are not affected. Reproduction Output: <titlealice - Dashboard - Gitea: Git with a cup of tea</title — attacker is logged in as alice with one header, no password, no cookie. Same payload with X-WEBAUTH-USER:…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  25. Critical, CVSS 9.6GoPublished

    Gitea: Incomplete SSRF Protection in Webhook and Migration Allow-list Default Filter

    CVE-2026-22874 · GHSA-2r5c-gw76-rh3w

    Affected
    • Go code.gitea.io/gitea < 1.26.3
    Fixed in
    1.26.3· Vendor fix available
    Issue
    Gitea's default SSRF allow-list (MatchBuiltinExternal, used by both webhook delivery and repository migrations) relies on Go's standard library net.IP.IsPrivate(), which only covers RFC 1918 and RFC 4193. As a result, several IP ranges commonly used for cloud metadata services, internal networks, and IPv6 transition mechanisms are not blocked, allowing authenticated users to send HTTP requests to those destinations and read the responses via the webhook history UI. Details The vulnerability lives in HostMatchList.checkIP, specifically line 103: net.IP.IsPrivate() recognises only: - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (RFC 1918) - fc00::/7 (RFC 4193 IPv6 ULA) It does not recognise: | Range | Description | |---|---| | 100.64.0.0/10 | RFC 6598 Carrier-Grade NAT | | 168.63.129.16/32 | Azure WireServer metadata endpoint | | 172.32.0.0/11 | Non-RFC1918 portion of 172.0.0.0/8 (real-world internal use) | | 64:ff9b::/96 | RFC 6052 IPv6 NAT64 (can embed 169.254.169.254) | |…

    Recommended action: Upgrade to 1.26.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →