The Gitea 9.8: File Read, Token Theft, and a Git Hook Later

If you self-host Gitea, check your version before you read the rest of this.

CVE-2026-59774 got its formal advisory on August 2 with a CVSS score of 9.8. That score is not a typo.

The bug

An unauthenticated attacker hits the markup rendering endpoint of any public repository and submits Org-mode markup with an #+INCLUDE directive pointing at an absolute path. The server resolves it and renders the file contents. No login. No write access. Just a well-crafted request.

The root cause is almost embarrassing in its simplicity: Gitea initializes the go-org library without overriding its default ReadFile callback. One missing override, and the server reads arbitrary files for anyone who asks.

Affected versions: 1.22.1 up to 1.27.0. Fixed in 1.27.1.

Why it's a 9.8

File read alone is bad. The escalation chain is worse. Gitea's own advisory walks through it:

  1. Read app.ini through the file-read bug.
  2. Extract INTERNAL_TOKEN from it.
  3. Inject a Git hook through the internal logger.
  4. Trigger it during an anonymous clone.

That's remote code execution with four extra steps. A "file read" that ends with you running code on the box. This is why the score is what it is, and why the advisory notes that instances with even one public repository and internet exposure should treat this as active.

You are the patch cycle

Here's the part that never makes it into the release notes: when you self-host, you own the patch cycle. No managed provider will email you about this. No maintenance window rolls out for you. You are the maintenance window.

This is the trade you made when you decided to run your own git server. The upside is you control everything. The downside is that "everything" includes the security updates.

What to do

  1. Update to 1.27.1 or later. Today, not next weekend.
  2. Rotate INTERNAL_TOKEN after the update. If you were read before you patched, that token is already out there.
  3. No public repos? Patch anyway. Less attack surface, not none.
  4. Smoke test after the update: clone, push, browse the web UI once. Ten minutes, and it beats discovering a broken install at the worst possible moment.

That's the whole job. One CVE, one update, one rotated token. Welcome to self-hosting.

Sources: Gitea 1.27.1 release notes The Hacker News write-up Self-Hosted Weekly W32 roundup