# Gitea's Org-Mode Renderer Handed Attackers a Server Filesystem Key — No Login Required


## The Threat


Gitea, the widely-deployed self-hosted Git platform, shipped a critical file-read vulnerability in versions 1.22.1 through 1.27.0 that required nothing from an attacker beyond a public repository and a crafted document. No credentials. No write access. A single POST request to the markup rendering endpoint could return any file readable by the Gitea service account — private SSH keys, database credentials, application secrets, and more.


The root cause lives in the Org-mode renderer. Gitea 1.27.0 initialized the go-org parsing library using org.New() without overriding the library's default ReadFile callback, which maps directly to ioutil.ReadFile. Org-mode's #+INCLUDE directive accepts absolute filesystem paths, and with that callback intact, the renderer dutifully fetched them from disk and returned the contents. The attack surface was the markup rendering endpoint, POST /{owner}/{repo}/markup, which allows anonymous access against any repository with its code unit enabled.


That "public repository" requirement does provide a meaningful constraint — instances with no public repos have no unauthenticated path through this endpoint. But any Gitea deployment running a public project, an open-source mirror, or a demo repo is fully exposed. Given Gitea's heavy adoption in DevOps pipelines, open-source communities, and air-gapped enterprise environments, the count of affected instances is substantial. The file-read primitive alone is dangerous. But Gitea's own advisory describes an escalation path: read app.ini, extract INTERNAL_TOKEN, inject a Git hook through the internal logger, trigger that hook during an anonymous clone. That chain converts file-read into remote code execution.


## Severity and Impact


| Field | Detail |

|---|---|

| CVE | CVE-2026-59774 |

| CVSS Score | 9.8 (Critical) |

| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |

| Attack Complexity | Low |

| Privileges Required | None |

| User Interaction | None |

| CWE | CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) |

| Publicly Known | Yes — file-read primitive previewed before formal advisory |

| Exploitation in Wild | None confirmed as of August 5, 2026 |

| KEV Listed | No |


## Affected Products


Gitea (self-hosted)

  • Versions 1.22.1 through 1.27.0 (all builds)
  • Cloud-hosted Gitea instances (automatically patched during maintenance window)

  • Fixed in

  • Gitea 1.27.1 (also patches CVE-2026-60004, a separate RCE bug)

  • The fix is in PR #38642, backported via PR #38645. Gitea overrides the go-org ReadFile callback so that Org-mode include paths render as literal content rather than resolving against the server filesystem.


    ## Mitigations


    Immediate action


  • Upgrade to Gitea 1.27.1 — this is the only complete fix. Self-hosted administrators should treat this as an emergency patch.
  • Cloud-managed Gitea instances were upgraded automatically; verify your version in the admin panel.

  • If exposure is suspected


    Upgrading alone is not sufficient if the instance was reachable during the vulnerability window. Review access logs for anonymous POST requests to /{owner}/{repo}/markup, particularly those selecting Org-mode mode or submitting absolute filesystem paths. If hits appear on an affected version:


    1. Rotate INTERNAL_TOKEN in app.ini

    2. Rotate all OAuth tokens, JWT signing keys, and database credentials accessible to the service account

    3. Inspect repository hook directories (hooks/ under each repo) for unexpected executable files that could indicate the escalation chain was attempted

    4. Assume any file the service account could read should be considered compromised


    Preventive hardening (defense in depth)


  • Run the Gitea service account with the minimum filesystem permissions necessary — least privilege limits what an attacker can read even if a similar flaw emerges
  • Disable public repository access if your use case doesn't require it; this removes the unauthenticated precondition entirely
  • Place the Gitea markup endpoint behind network controls that restrict anonymous internet access where operationally feasible

  • ## References


  • [Gitea Security Advisory — CVE-2026-59774](https://github.com/go-gitea/gitea/security)
  • [Gitea 1.27.1 Release](https://github.com/go-gitea/gitea/releases/tag/v1.27.1)
  • [Fix PR #38642](https://github.com/go-gitea/gitea/pull/38642)
  • [Backport PR #38645](https://github.com/go-gitea/gitea/pull/38645)
  • [XBOW Security](https://xbow.com)

  • ---


    ## HackWire Analysis


    This vulnerability is a useful case study in how "low severity" prerequisites collapse under scrutiny. The instinct when reading "requires a public repository" is to mentally downgrade the risk. In practice, Gitea's most common deployment patterns work against defenders here: open-source projects, internal developer portals with a few public-facing repos, and staging environments mirroring production — all are exposed. The constraint is real but narrow.


    What makes CVE-2026-59774 worth watching beyond the immediate patch cycle is the escalation chain. Gitea describes a path from file-read to remote code execution through the internal token and Git hook injection. As of this writing, no independently verified exploit demonstrating that chain exists, and Gitea's KEV absence suggests no confirmed weaponization. But the file-read primitive was publicly previewed before the formal August 2 advisory. That gap between "known" and "patched" is where threat actors operate.


    The broader pattern here is also worth flagging. This is Gitea's third critical-severity advisory in roughly three months: the container registry access control flaw in May (CVE-2026-27771, estimated 30,000+ affected deployments), the reverse-proxy authentication bypass in June (CVE-2026-20896, observed being probed 13 days after disclosure), and now this. A platform accumulating critical patches at this pace deserves elevated scrutiny from security teams running it in sensitive environments. Three separate critical bugs in a single quarter is not a coincidence — it suggests either a sustained researcher focus on the codebase or structural gaps in the pre-release security review process.


    For defenders in DevOps-heavy environments: treat your Gitea app.ini the way you'd treat a root SSH key. If there's any chance it was readable, rotate everything downstream from it.


    — HackWire Editorial


    ## Related Coverage


  • Read more in our [Vulnerabilities](https://www.hackwire.news/category/vulnerabilities) coverage
  • Cross-reference with [Breaches](https://www.hackwire.news/category/breaches) and [Malware](https://www.hackwire.news/category/malware)
  • Stay current via the [HackWire homepage](https://www.hackwire.news/)