Every app that lets strangers sign up is an unauth RCE waiting on one box
Two remote-code-execution bugs landed in self-hosted tools in the last few weeks, and read together they make a point I keep having to relearn on my one-box setup: the dangerous thing isn't always the bug. It's who's allowed to reach it, and what else is sharing the box when they do.
Exhibit A: Gitea, where "authenticated" means "anyone"
CVE-2026-60004 (advisory GHSA-rcr6-4jqh-j84m, CVSS 9.8) is an RCE in Gitea's diffpatch endpoint. Mechanically it needs a user with write access to a repository: apply a crafted patch twice, trigger a Git three-way-merge fallback, and you can write an executable post-index-change hook into the bare clone's hooks/ directory, which fires on the next index update. Fixed in Gitea 1.27.1; everything from 1.17 up is affected, and a public proof-of-concept exists. (Forgejo, a Gitea fork, reportedly shares the code and shipped its own fixes — worth checking if you run it. And note the CVE is still marked reserved on NVD, so cite the GitHub advisory, not NVD.)
"Needs write access" sounds like a real barrier. It isn't, because Gitea ships with open registration on by default: no email confirmation, no admin approval, new users aren't restricted. So an anonymous visitor signs up, creates a repo (now they have write access to it), and exploits the bug. That's why the CVSS vector carries "privileges required: none" despite a code path that nominally needs a logged-in user. Open registration collapsed the authentication barrier to a formality.
Exhibit B: n8n, where the automation tool can write to its own guts
CVE-2026-21877 (CVSS 9.9) is an RCE in n8n's Git node. A low-privileged authenticated user can get an arbitrary file write, because the underlying Git library bypasses n8n's path-validation helpers and lets a write land inside the repo's .git directory — a hook, again. Fixed in 1.121.3, and it affects both self-hosted and n8n Cloud. The 9.9 comes from the scope change: code execution as the service user inside the container is a foothold, not the finish line.
A vulnerability is a lock that can be picked. Open registration is leaving the front door open so nobody has to pick it. Co-location is discovering every interior door was unlocked too.
The two lessons for one box
1. Default-open signup turns "authenticated RCE" into "unauthenticated RCE." This is the whole reason the Gitea bug is a 9.8 and not a 7-point-something. Every app on your box that lets strangers register is a bug away from anonymous code execution. The first hardening pass isn't patching — it's inventorying which of your self-hosted apps allow public sign-up and turning it off where you don't need it. For Gitea that's one line: DISABLE_REGISTRATION = true.
2. Co-located apps share a blast radius. Both of these bugs give an attacker code execution as the service user inside a container. On a single Docker host where everything hangs off the same default bridge network, that foothold can reach sibling containers and databases at the network level. Your public blog, your Git forge, your automation tool, your database — one RCE in the weakest of them is a pivot into the rest. "It's all on one box" is a convenience I chose; it's also a decision about how far an attacker gets on their first success.
What I actually do about it
None of this is exotic; it's the boring hygiene that co-location makes non-optional:
- Kill open registration on anything that doesn't genuinely need public sign-up.
- Segment Docker networks — per-app user-defined bridges instead of one shared default, and internal-only networks for databases so a compromised web app can't reach a sibling app's DB.
- Drop privileges in the container —
cap_drop: ALL,no-new-privileges, a non-root user, read-only filesystem where you can. - Don't co-locate high-privilege automation with a public site. A tool like n8n, whose entire job is to run arbitrary actions, is exactly the thing I don't want one hop away from a public-facing container.
- Patch promptly — Gitea 1.27.1, n8n 1.121.3 — and run something that tells you when you're behind.
The honest summary: on one box, the CVE is only ever half the story. The other half is the front door you left open and the interior walls you never built. You can't always control when a dependency ships an RCE. You can absolutely control whether a stranger can reach it, and how much of your box they own once they do.