Skip to content
Try Gitea Cloud ☁️ for 30 days → Accelerate your Development & Deploys!
Gitearelease

Gitea 1.27.3 is released

1.27.3Release

We are excited to announce the release of Gitea 1.27.3, the third patch release for the 1.27 series. It contains a large batch of security fixes covering Gitea Actions, the API, the package registry and repository migration, alongside bug fixes for Actions, packages and the UI. We strongly recommend that all users upgrade as soon as possible.

This release addresses the following security vulnerabilities. Please upgrade as soon as possible.

  • CVE-2026-66877: The “approve workflow runs from first-time fork contributors” gate was enforced only by inserting a run’s jobs as blocked, and the job emitter never re-checked run.NeedApproval. An unrelated run sharing a job-level concurrency group could force an emitter pass that unblocked and dispatched an approval-pending fork pull request’s jobs to runners without any approval, enabling code execution on self-hosted runners by anyone who can open a pull request. Fixed by #39005 / #39018. Thanks to @klydz for reporting the issue, and to @bircni for the patch.
  • CVE-2026-71184: The maintainer-approval gate for fork pull request workflows was skipped for the pull_request_review_comment event (and review approved/rejected), because the notifier never called .WithPullRequest(pr) and a nil pull request is not treated as a fork pull request. Workflow YAML from the fork head then ran on the base repository without approval. Fixed by #39005 / #39018. Thanks to @echoesofwhoami for reporting the issue, @iabdullah215 for the analysis, and to @bircni for the patch.
  • CVE-2026-68957: The issue-search API and web route let an account marked is_restricted search and read issues belonging to Limited-visibility users, exposing full issue titles and bodies as well as content matched through titles, bodies or comments. Anonymous issue search correctly returns nothing. Fixed by #39004 / #39039. Thanks to @Mon3mRT and @Black1hp for reporting the issue, and to @bircni and @silverwind for the patch.
  • CVE-2026-60010: PUT /api/v1/repos/{owner}/{repo}/teams/{team} let a non-owner repository admin attach arbitrary organization teams to a private repository even when the organization had disabled that with RepoAdminChangeTeamAccess=false. This is a sibling of an earlier team-side fix that the repo-side endpoint did not receive. Fixed by #39046 / #39058. Thanks to @akoul for reporting the issue, and to @bircni for the patch.
  • CVE-2026-70406: The shared parseCompareInfo helper — used by both CompareDiff and CreatePullRequest — lacked the TokenCanAccessRepo(headRepo) guard that was added to UpdatePullRequest for an earlier advisory, so a public-only, read:repository token could read commit history and diff content from a private head repository by routing through a public base repository’s compare endpoint. Fixed by #39006 / #39013. Thanks to @qw3rtyou for reporting the issue, and to @bircni for the patch.
  • CVE-2026-63792: CanReadWorkflowCrossRepo granted cross-repository read of reusable workflow files through the “collaborative owner” trust relationship without checking whether the run was a fork pull request, disclosing another private repository’s workflow file contents. This is a missed sibling of an earlier fix that only touched GetActionsUserRepoPermission. Fixed by #39005 / #39018. Thanks to @krishna-loginsoft for reporting the issue, and to @bircni for the patch.
  • CVE-2026-66874: For a pull_request event Gitea reads the workflow definition from the fork-controlled pull request head to emit a synthetic skipped commit status for workflows excluded by their own branches: / paths: filter. A fork author could name such a workflow to match a required status check context and give it a never-matching filter, marking the required check as satisfied without any workflow running. Fixed by #39005 / #39018. Thanks to @iabdullah215 and @effabinteashfaq for reporting the issue, and to @bircni for the patch.
  • CVE-2026-68964: The API returned the SSH and GPG keys of Limited-visibility users — key titles, public key material, fingerprints, and the email addresses embedded in GPG keys — to restricted callers, while the equivalent web routes correctly returned 404. Fixed by #39004 / #39039. Thanks to @Mon3mRT and @Black1hp for reporting the issue, and to @bircni and @silverwind for the patch.
  • CVE-2026-67577: The activity-feed and contribution-heatmap API routes returned a Limited-visibility user’s activity to restricted callers, while the profile and RSS routes returned 404. Fixed by #39004 / #39039. Thanks to @Mon3mRT and @Black1hp for reporting the issue, and to @bircni and @silverwind for the patch.
  • CVE-2026-66849: determineAccessMode granted any non-ghost logged-in user read access to packages owned by a Limited-visibility user without excluding restricted accounts, so a restricted user could enumerate and download another user’s full package registry. Fixed by #39043 / #39058. Thanks to @Black1hp and @Mon3mRT for reporting the issue, and to @bircni for the patch.
  • CVE-2026-73135: One of several SQL predicates meant to enforce the same repository-visibility policy behaved differently for hidden users, so some authenticated repository-search endpoints — and the anonymous forks and watched-repositories listings — exposed repositories owned by hidden users. Fixed by #39009 / #39012. Thanks to @LongNguyen1708 for reporting the issue, and to @bircni for the patch.
  • CVE-2026-78433: Attachments created before the 16 January 2026 legacy cutoff skipped the cross-repository check entirely, because the guard keyed only on the timestamp and not also on RepoID == 0. Permission was then evaluated against the repository named in the URL rather than the one owning the attachment, so a private repository’s attachment could be fetched through any public repository’s attachment path. Fixed by #39048 / #39077. Thanks to @iabdullah215 for reporting the issue, and to @bircni and @silverwind for the patch.
  • CVE-2026-70407: GET /api/v1/orgs did not enforce the read:organization token scope, so a token with only read:misc could list organization metadata — including limited and private organizations when the token belonged to a site admin. Fixed by #39041 / #39058. Thanks to @gxy1113, @iabdullah215 and @rajivraj for reporting the issue, and to @bircni for the patch.
  • CVE-2026-73126: The Actions workflow-badge endpoint did not enforce Personal Access Token scopes, so a token with only read:user, or a read:repository,public-only token, could retrieve the latest workflow status of a private repository accessible to the token owner. Fixed by #39044 / #39058. Thanks to @0xDBJ for reporting the issue, and to @bircni for the patch.
  • CVE-2026-70400: POST /api/v1/repos/migrate accepted a public-only repository token and created a private repository when the request body set private: true, even though the normal private repository creation route rejects the same token. Fixed by #39007 / #39014. Thanks to @rexpository for reporting the issue, and to @bircni for the patch.
  • CVE-2026-70396: POST /api/v1/orgs/{org}/repos allowed a token scoped only to write:organization to create repositories inside an organization, bypassing the repository-scope requirement enforced on sibling repository-creation routes. Fixed by #39007 / #39014. Thanks to @rexpository for reporting the issue, and to @bircni for the patch.
  • CVE-2026-63021: Swift package upload parsed every shallow Package.swift / Package@swift-N.swift into memory before any quota or persistence check, rejecting only individual files larger than 128 KiB with no entry-count or aggregate-size cap. A few-megabyte archive of many highly compressible manifests could amplify into tens to hundreds of megabytes of resident memory. Fixed by #39025 / #39032. Thanks to @DshtAnger for reporting the issue, and to @bircni for the patch.
  • CVE-2026-62925: The Alpine package upload handler parsed .apk contents before the size-quota check and never wrapped the gzip/tar streams in a limit reader, unconditionally appending every provides= / depend= value from .PKGINFO into a slice, so a few-hundred-kilobyte .apk could amplify into process memory. Fixed by #39026 / #39029. Thanks to @DshtAnger for reporting the issue, and to @bircni for the patch.
  • CVE-2026-73273: When a Maven artifact is uploaded with a checksum extension (.md5, .sha1, .sha256, .sha512), Gitea buffered the entire request body into memory and returned before CheckSizeQuotaExceeded ran, so the checksum path had neither a size quota nor a read bound though a valid checksum is at most a few dozen bytes. Fixed by #39028 / #39031. Thanks to @rajivraj for reporting the issue, and to @bircni for the patch.
  • CVE-2026-60021: The GitLab migration path probed the remote /api/v4/version endpoint without propagating the migration context and with a timeout-less HTTP client, so a malicious GitLab-compatible server could keep the response open indefinitely and pin migration workers even after the task was stopped. Fixed by #39023 / #39035. Thanks to @PhucQuan for reporting the issue, and to @bircni for the patch.
  • CVE-2026-60018: The OneDev migration path read the entire /~api/version/server response body with io.ReadAll before validating the version string, so a malicious OneDev server could return a very large or never-ending response and hold migration workers and memory until timeout. Fixed by #39024 / #39033. Thanks to @PhucQuan for reporting the issue, and to @bircni for the patch.
  • CVE-2026-73130: The gitignores repository-creation field had no size limit on either the web form or the API option struct, so an oversized value produced linear amplification of template reads during repository creation. Fixed by #39027 / #39040. Thanks to @arpitjain099 for reporting the issue, and to @bircni and @wxiaoguang for the patch.
  • CVE-2026-70402: Server-side Git hook directories and scripts were created with mode 0777 before the process umask was applied. With a permissive umask (0000 / 0002) the resulting files were group- or world-writable, allowing a local user to modify them and run code as the Gitea service account. Fixed by #39008 / #39016. Thanks to @What-canIsay for reporting the issue, and to @bircni and @silverwind for the patch.
  • CVE-2026-66853: DoerViewOtherVisibility returned VisibleTypeLimited for any signed-in, non-admin, non-self viewer without checking IsRestricted, so GET /users/{username}/orgs let a restricted user enumerate Limited-visibility organizations along with their name, description and avatar. Fixed by #39047 / #39058. Thanks to @Black1hp and @Mon3mRT for reporting the issue, and to @bircni for the patch.
  • CVE-2026-71301: In a private repository, a Wiki-only member could use POST /{owner}/{repo}/markup to resolve a same-repository pull request reference and read its title despite having neither Issues nor Pull Requests access. Fixed by #39045 / #39054. Thanks to @hexcraft-labs for reporting the issue, and to @bircni, @silverwind and @wxiaoguang for the patch.
  • CVE-2026-73504: The raw Actions artifact download endpoint looked up the artifact before validating the signed URL, so an unauthenticated request returned 401 when the supplied global artifact ID existed and a different response otherwise, forming an artifact-to-repository existence oracle. Fixed by #39049 / #39053. Thanks to @hexcraft-labs for reporting the issue, and to @bircni and @silverwind for the patch.

This release also hardens issue search so that an unfiltered query no longer enumerates every public repository into the indexer filter (#39000, by @lunny), and removes unsafe code from the internal private endpoints (#38965, by @wxiaoguang).

  • Step-level continue-on-error accepts an expression again instead of rejecting the whole workflow file when the value is not a plain boolean (#39148).
  • Workflows using YAML anchors and aliases are resolved once, before the workflow is split per job, so aliases that cross job boundaries no longer fail (#38996).
  • Matrix legs are grouped in the workflow graph by their real job identity rather than by parsing display names, fixing both missing and bogus matrix panels (#38998).
  • The “Complete job” log group is shown when the last step is skipped (#39003), and non-mapping matrix include / exclude entries are rejected (#38933).
  • Swift Registry preserves SemVer prerelease identifiers instead of dropping them (#39158).
  • OpenPGP signature verification is no longer attempted with an SSH instance key when SIGNING_FORMAT = ssh, which previously logged an export error for every signed commit (#39086).
  • The pull request merged state is kept in sync with git (#39118), default compare links name the head repository (#39079), and co-author trailers that are not RFC 5322 addresses are parsed (#39081).
  • MarkAsBrokenEmpty is not triggered while a repository is still being migrated (#39092).
  • The runner list page keeps its query parameters (#39163), the dashboard feed respects FEED_PAGING_NUM (#38936), scoped labels are sorted by exclusive order in dropdowns (#38954), and anonymous theme switching works when REQUIRE_SIGNIN_VIEW is set (#38961).
  • Limited-visibility organizations grant the same unit read access (Code, Packages, Projects) to authenticated non-members as public organizations (#38963).
  • The login_name field is optional again when editing a user through the API (#38945), the bleve indexer token filters are corrected (#38951), and environment variables are honored during install (#38976).

This release includes 41 merged pull requests, thanks to the amazing contributions from our community.

Download our pre-built binaries from the Gitea downloads page — make sure to select the version compatible with your platform. For a step-by-step guide on installation or upgrades, check out our installation documentation

We would also like to thank all of our supporters on Open Collective who are helping to sustain us financially.


Looking for a seamless, hassle-free solution to manage your Git repositories? Discover Gitea Cloud — A fully-managed, scalable platform designed to streamline your development workflow.

  • SECURITY
    • fix(packages): restrict/limited/token-scope access (#39041, #39043, #39044, #39047, #39046) (#39058)
    • fix(attachments): enforce owning repository path (#39048) (#39077)
    • fix(markup): enforce same-repository issue access (#39045) (#39054)
    • fix(actions): verify raw artifact signatures first (#39049) (#39053)
    • fix(api): hide limited users from restricted viewers (#39004) (#39039)
    • fix(repo): limit gitignore template selections (#39027) (#39040)
    • fix(migrations): cancel GitLab version probes (#39023) (#39035)
    • fix(packages): limit Swift package manifests (#39025) (#39032)
    • fix(migrations): bound OneDev version responses (#39024) (#39033)
    • fix(packages): limit Maven checksum uploads (#39028) (#39031)
    • fix(packages): bound Alpine metadata entries (#39026) (#39029)
    • fix(actions): enforce fork pull request trust boundaries (#39005) (#39018)
    • fix(git): restrict hook permissions (#39008) (#39016)
    • fix(api): enforce repository creation token authorization (#39007) (#39014)
    • fix(api): enforce public-only scope for compare heads (#39006) (#39013)
    • fix(repo): hide repositories of hidden owners (#39009) (#39012)
    • fix: avoid enumerating every public repository in issue search (#38992) (#39000)
    • refactor: private endpoints (#38964) (#38965)
  • ENHANCEMENTS
    • enhance: add permalinks to pull request reviews (#38849) (#39036)
  • BUGFIXES
    • fix: add missing query parameters on runner list page (#39163)
    • fix(actions): keep step-level continue-on-error expressions unevaluated (#39141) (#39148)
    • fix(packages): preserve SemVer prerelease identifiers in Swift Registry (#39156) (#39158)
    • fix(repo): prevent MarkAsBrokenEmpty when repository is being migrated (#39091) (#39092)
    • fix(asymkey): do not verify OpenPGP signatures with an SSH instance key (#39073) (#39086)
    • fix(pull): keep the merged state in sync with git (#39062) (#39118)
    • fix(pull): name the head repository in default compare links (#39075) (#39079)
    • fix(git): parse co-author trailers that are not RFC 5322 addresses (#39076) (#39081)
    • fix(actions): show “Complete job” logs when the last step is skipped (#38939) (#39003)
    • fix(actions): Fix how jobs in matrixes are grouped (#38980) (#38998)
    • fix: resolve YAML anchors and aliases in Actions workflows (#38984) (#38996)
    • fix: honor environment variables during install (#38974) (#38976)
    • fix: grant limited-org unit read access to authenticated non-members (#38871) (#38963)
    • fix: allow anonymous theme switching when REQUIRE_SIGNIN_VIEW is set (#38956) (#38961)
    • fix(actions): drop wrapper span around the action status icon (#38957) (#38959)
    • fix(issues): sort scoped labels by exclusive order in dropdowns (#38893) (#38954)
    • fix(indexer): correct bleve indexer token filters (#38853) (#38951)
    • fix: make “login_name” field optional for API edit user (#38917) (#38945)
    • fix(actions): reject non-mapping matrix include/exclude (#38933)
    • fix(ui): respect FEED_PAGING_NUM on the dashboard feed (#38935) (#38936)
  • MISC
    • chore: repo compare link (#39088) (#39119)
    • ci: remove AWS S3 uploads from release workflows (#38928) (#38929)
    • chore: Pre-register a builtin OAuth2 application for the official Gitea mobile app (#38880) (#38922)