{
 "version": "https://jsonfeed.org/version/1.1",
 "title": "Gitea: important CVE events",
 "home_page_url": "https://patchwire.jonathanross.dev/products/gitea--gitea/",
 "feed_url": "https://patchwire.jonathanross.dev/feeds/products/gitea--gitea/important.json",
 "authors": [
  {
   "name": "Patchwire"
  }
 ],
 "language": "en",
 "items": [
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-109553/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-109553/",
   "title": "CVE-2026-109553 · Gitea · disclosed",
   "content_text": "Gitea resolved the principals of an SSH certificate by searching the content of all stored public keys instead of only principal keys. When Gitea trusts a user certificate authority (`SSH_TRUSTED_USER_CA_KEYS`) and accepts arbitrary principals (`SSH_AUTHORIZED_PRINCIPALS_ALLOW=anything`), a user could register another user's public key line as their own principal, or a holder of a certificate signed by that authority could list it, and then authenticate as the owner of that key through the HTTP signature API and the built-in SSH server. Instances that do not trust a user certificate authority are not affected.",
   "date_published": "2026-10-18T18:51:31Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-73804/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-73804/",
   "title": "CVE-2026-73804 · Gitea · disclosed",
   "content_text": "Gitea allows a token with write:user scope to register an attacker-controlled SSH public key on the token owner's account. API requests signed with the corresponding private key authenticate as that account through HTTP Signature without API token scope information, causing route-level token scope checks to be skipped. This converts a user-scoped token into an unscoped API authentication method while retaining the account's normal role and repository permissions.",
   "date_published": "2026-10-14T14:38:00Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-73800/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-73800/",
   "title": "CVE-2026-73800 · Gitea · disclosed",
   "content_text": "Gitea resolves local reusable workflow files from a fork's head commit when a trusted base-branch workflow runs for a pull_request_target event. A fork author can modify a referenced reusable workflow so attacker-controlled code executes with the repository and organization secrets available to that event. Exploitation requires a base workflow that calls a local reusable workflow, and bypasses the intended separation between trusted base code and untrusted fork code.",
   "date_published": "2026-10-14T14:37:49Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-73539/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-73539/",
   "title": "CVE-2026-73539 · Gitea · disclosed",
   "content_text": "Gitea substitutes a URL derived from the markup Context field into external renderer command templates without escaping the reference path before shell-style argument splitting. A crafted Context can inject additional renderer arguments, including options that load executable filter files. On deployments using a susceptible external renderer such as pandoc, a user who can place a filter file at an accessible path can cause it to execute as the Gitea service account; the public repository markup endpoint itself can be reachable without authentication.",
   "date_published": "2026-10-14T14:37:44Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-73535/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-73535/",
   "title": "CVE-2026-73535 · Gitea · disclosed",
   "content_text": "Gitea's OpenID connect handler accepts a user's password without enforcing enrolled TOTP or WebAuthn verification before completing sign-in and linking an OpenID identifier. When OpenID sign-in is enabled, an attacker who knows the victim's password can obtain a session and link an attacker-controlled identifier. The attacker can then sign in through that identifier without the victim's password or second factor, and a password change does not remove the link.",
   "date_published": "2026-10-14T14:37:39Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-71184/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-71184/",
   "title": "CVE-2026-71184 · Gitea · disclosed",
   "content_text": "Gitea's pull request review notifier does not attach the pull request to the Actions notification, so the fork workflow approval gate does not recognize the run as originating from a fork. Review comment and review approval or rejection events can consequently load workflow code from the fork head and run it on the base repository's runners without the required maintainer approval. This allows execution of fork-controlled workflow code across the intended approval boundary.",
   "date_published": "2026-10-14T14:37:05Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-66877/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-66877/",
   "title": "CVE-2026-66877 · Gitea · disclosed",
   "content_text": "Gitea enforces first-time fork contributor approval by blocking jobs, but some job transition and dispatch paths do not re-check the run's approval requirement. A separate run sharing a job-level concurrency group can cancel a pending job and cause its blocked sibling jobs to be re-emitted and dispatched without approval. This allows unreviewed workflow code to execute on self-hosted runners; fork secrets remain withheld and the run token remains read-only.",
   "date_published": "2026-10-14T14:36:11Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-59774/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-59774/",
   "title": "CVE-2026-59774 · Gitea · disclosed",
   "content_text": "Gitea's Org-mode markup renderer processes INCLUDE directives supplied to the repository markup endpoint without preventing access to server-side files. An unauthenticated attacker can use a suitable public repository to read files accessible to the Gitea service account. If the disclosed files include app.ini and its INTERNAL_TOKEN, the attacker can chain the disclosure with internal logger access to modify a Git hook and execute commands as the Gitea service account.",
   "date_published": "2026-10-14T14:28:25Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-105267/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-105267/",
   "title": "CVE-2026-105267 · Gitea · disclosed",
   "content_text": "The Gitea web route for deleting tags (`POST /{owner}/{repo}/tags/delete`) requires only write access to the Code unit, but shares its handler with release deletion and did not check that the target was a plain tag. A collaborator with Code write access and without Releases write access could permanently delete published releases of that repository, including their attachments. Protected tag rules covering the release tag still blocked the deletion.",
   "date_published": "2026-10-06T21:35:35Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-101023/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-101023/",
   "title": "CVE-2026-101023 · Gitea · disclosed",
   "content_text": "Gitea's OAuth2 token endpoint verified the signature and grant of a token submitted with the `refresh_token` grant type, but not that the token was a refresh token. An unexpired access token for the same OAuth2 application and grant could be exchanged for a new access token and refresh token. Whoever holds such an access token could keep access beyond the token's original lifetime.",
   "date_published": "2026-10-06T21:34:53Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-86684/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-86684/",
   "title": "CVE-2026-86684 · Gitea · disclosed",
   "content_text": "The Gitea push mirror API checked whether the repository owner, instead of the requesting user, may use local file system paths. On instances with `[security] IMPORT_LOCAL_PATHS = true`, a repository administrator who is not allowed to import local paths could add a push mirror to a local path on the server when the repository owner has that permission. Gitea then pushed the repository's refs into an existing Git repository at that path with the permissions of the Gitea process.",
   "date_published": "2026-10-06T21:17:09Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-73278/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-73278/",
   "title": "CVE-2026-73278 · Gitea · disclosed",
   "content_text": "Gitea's OAuth2 and OpenID Connect sign-in paths do not require a WebAuthn challenge when WebAuthn is the account's only configured second factor. A party able to authenticate through the affected external identity flow can obtain a full session without the passkey verification enforced during password login. One affected path can also persist an external identity link, extending the compromise beyond the initial session; accounts with TOTP configured are outside the reported WebAuthn-only scenario.",
   "date_published": "2026-10-06T19:33:54Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-96580/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-96580/",
   "title": "CVE-2026-96580 · Gitea · disclosed",
   "content_text": "Gitea expanded a workflow's static `strategy.matrix` into its full Cartesian product without a size limit when creating a run, before the fork pull request approval gate applied. A user who can open a pull request from a fork could submit a small workflow file whose matrix expands to a very large number of jobs, consuming server memory and potentially terminating the Gitea process. No runner is required. Static matrices above 256 combinations are now rejected before expansion.",
   "date_published": "2026-10-06T19:25:33Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-96404/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-96404/",
   "title": "CVE-2026-96404 · Gitea · disclosed",
   "content_text": "When Gitea's web installer is reachable against a database that already contains users, such as after `INSTALL_LOCK` has been reset to `false`, submitting the install form with an administrator username matching an existing account issued an authenticated session for that account without verifying its password. If the account is an administrator, the session grants full administrative access, including changing the account's password. Databases with a single user also did not require the reinstall confirmation.",
   "date_published": "2026-10-06T19:25:28Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-96399/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-96399/",
   "title": "CVE-2026-96399 · Gitea · disclosed",
   "content_text": "A repository's external issue tracker regular expression containing alternating capture groups could produce invalid slice indexes when Gitea rendered issue references, causing a runtime panic that terminated the Gitea process. A user who can edit a repository's external issue tracker settings could make any later rendering of matching content, such as viewing a README, crash the instance for all users.",
   "date_published": "2026-10-06T19:25:18Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-94205/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-94205/",
   "title": "CVE-2026-94205 · Gitea · disclosed",
   "content_text": "Gitea Actions decided whether a fork pull request run needed approval based on the user who triggered the event rather than the pull request author. For `pull_request` activity triggered by a maintainer during ordinary triage, such as adding a label, the run was created without requiring approval, while the workflow definition was still taken from the fork head. Where Actions is enabled and a matching runner is registered, fork-controlled workflow code could run on the base repository's runners without an explicit approval.",
   "date_published": "2026-10-06T19:25:04Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-79960/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-79960/",
   "title": "CVE-2026-79960 · Gitea · disclosed",
   "content_text": "When a push was authenticated with a deploy key, Gitea recorded the repository owner as the pusher, so permission checks in the push hook pipeline evaluated the owner instead of the deploy key. A holder of a writable deploy key could create protected tags without being on the tag allow list and change repository visibility through push options, for example making a private repository public. Pull requests created through the AGit flow with a deploy key were also attributed to the owner.",
   "date_published": "2026-10-06T19:24:55Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-70357/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-70357/",
   "title": "CVE-2026-70357 · Gitea · disclosed",
   "content_text": "Gitea validates a repository migration hostname against its network allow and block lists before invoking Git, but the Git subprocess independently resolves the hostname when connecting. An attacker who can start a migration and control the destination's DNS can change the address between validation and connection to reach a blocked internal address. The affected path is the Git clone operation; validation in the migration HTTP client's dialer does not protect the independently connecting Git subprocess.",
   "date_published": "2026-10-06T19:24:50Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-104636/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-104636/",
   "title": "CVE-2026-104636 · Gitea · disclosed",
   "content_text": "Gitea validated the initial remote URL for push mirrors, wiki remote checks, and fetches of migrated pull request heads, but the subsequent raw Git operations followed HTTP redirects without revalidating the destination. A repository administrator using a policy-allowed endpoint that redirects could make Gitea's Git client send requests to an address that the outbound host policy would otherwise block. The impact depends on the configured policy and the internal services reachable from the server.",
   "date_published": "2026-10-06T19:24:45Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-103504/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-103504/",
   "title": "CVE-2026-103504 · Gitea · disclosed",
   "content_text": "Changing an organization team's permission through the API with only the `permission` field did not rebuild the team's per-unit access, and the requested level was not applied as a cap. After an organization owner demoted a team, for example from admin to read, the team's members kept their previous unit permissions, including write access to the team's repositories. The web form was not affected.",
   "date_published": "2026-10-06T19:24:26Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-95106/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-95106/",
   "title": "CVE-2026-95106 · Gitea · disclosed",
   "content_text": "Gitea accepted pushed Git trees containing two entries with the same name, which Git's own consistency checks reject. Gitea's web views resolved such a path to the first entry, while `git checkout`, Gitea Actions, and release archives use the last. A contributor could open a pull request whose diff and file views show benign content while CI and checkouts at the same commit use different, attacker-controlled content. Incoming objects are now checked for consistency; objects already stored in existing repositories are not rescanned.",
   "date_published": "2026-10-06T19:23:57Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-89430/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-89430/",
   "title": "CVE-2026-89430 · Gitea · disclosed",
   "content_text": "Gitea validated a push mirror's remote address against the `[migrations]` allow and block lists only when the mirror was created. Each synchronization passed the stored address directly to `git push`, so a name that later resolved to a blocked or internal address was still reached. A user with administrator access to a repository, which includes repositories they create themselves, could aim push mirror synchronization at internal Git services and force-push the repository's contents to them.",
   "date_published": "2026-10-06T19:23:52Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-103670/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-103670/",
   "title": "CVE-2026-103670 · Gitea · disclosed",
   "content_text": "When a Gitea Actions run was inserted, older runs in the same workflow-level concurrency group were cancelled without checking whether the new run still needed approval. Because fork pull request runs are inserted under the base repository, a user who can open a pull request from a fork could cancel trusted in-progress runs that share a concurrency group with `cancel-in-progress` enabled, without approval and without running any code. On self-hosted runners this can interrupt deployments and leave partial state behind.",
   "date_published": "2026-10-06T19:23:40Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-101027/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-101027/",
   "title": "CVE-2026-101027 · Gitea · disclosed",
   "content_text": "When `[migrations] ALLOWED_DOMAINS` was configured, a hostname matching the allow list was accepted without checking its resolved address against the local-network restrictions. A user who can start repository migrations and control the DNS of an allowed hostname could make it resolve to loopback or private addresses and bypass `ALLOW_LOCALNETWORKS = false`, reaching internal services from the Gitea server. Instances without `ALLOWED_DOMAINS` configured are not affected by this specific bypass.",
   "date_published": "2026-10-06T19:23:20Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-104626/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-104626/",
   "title": "CVE-2026-104626 · Gitea · disclosed",
   "content_text": "A user who can open a fork pull request can place workflow content with a shared run-level concurrency group into a Gitea Actions run that is awaiting approval. When a later run in that group cancels the blocked job, the run becomes terminal while still marked as needing approval. If a maintainer later approves the run, Gitea passed the already-cancelled job back through concurrency preparation, set it to waiting, and made it claimable by a matching runner, executing fork-controlled workflow code. Exploitation requires the maintainer's later approval action, Actions to be enabled, and a runner that accepts the repository's jobs.",
   "date_published": "2026-10-06T19:23:03Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-103059/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-103059/",
   "title": "CVE-2026-103059 · Gitea · disclosed",
   "content_text": "When Gitea's built-in SSH server is enabled (`START_SSH_SERVER = true`), the presented public key was looked up with an SQL `LIKE` comparison of its encoded content, which is case-insensitive on some databases, including the default SQLite. An attacker who can construct a case variant of another user's registered RSA public key for which they can derive the private key could have that key matched to the victim's account and authenticate over SSH as that user. Keys are now looked up by fingerprint.",
   "date_published": "2026-10-06T19:22:57Z"
  },
  {
   "id": "tag:patchwire.jonathanross.dev,2026:CVE-2026-104632/disclosed",
   "url": "https://patchwire.jonathanross.dev/cve/CVE-2026-104632/",
   "title": "CVE-2026-104632 · Gitea · disclosed",
   "content_text": "Gitea Actions blocks the jobs of workflow runs from first-time fork pull request contributors until a maintainer approves the run. The rerun path only required a run to be finished and built the new attempt's jobs without considering the pending approval, so when a user with Actions write access cancelled a run that was awaiting approval and then re-ran it, the new jobs were created as waiting rather than blocked while the run still recorded that approval was required. Cancelling and re-running stale fork checks is a routine action that does not involve the approval control, so where Actions is enabled and a matching runner is registered, workflow code taken from the fork pull request head could run on the repository's runners without an explicit approval.",
   "date_published": "2026-10-06T19:22:04Z"
  }
 ]
}
