Packet Path/

When RPKI Says 'Valid' But It's a Hijack: the maxLength Loophole

A forged BGP route carried the right origin number, fit inside a loose ROA, and passed RPKI as Valid. Here is how the August 2026 Softaculous incident worked—and how to close the gap.

Security · Intermediate · 10 min · October 5, 2026

Routing-security illustration showing a Valid stamp above a malicious route slipping through a broad ROA maxLength permission

Imagine a guard at a company parking gate. The guard checks that the photo on your badge matches your face. But the guard never asks how you got through the locked outer gate, who escorted you, or whether the badge owner approved this visit. The photo check can pass while the entry is still unauthorized.

That is the uncomfortable lesson in this BGP hijack. A narrow security check returned Valid. The route was still fraudulent.

In plain EnglishAttackers redirected traffic for part of Hetzner’s network by announcing a smaller, more-specific block. They made Hetzner’s real AS number appear at the end of the route, so RPKI’s limited origin check passed. A broad maxLength /24 setting also allowed that smaller block. Users could then reach attacker-controlled update servers without an RPKI warning.

The hijack, in numbers

At about 20:57 UTC on August 28, 2026, an unauthorized announcement appeared for 162.55.80.0/24. It came via AS62390, NexonHost, through transit AS6204, Zet.net. The advertised AS path ended with AS24940, Hetzner Online’s number, as the apparent origin. That final origin was forged.

An origin ASN is the autonomous-system number shown at the end of a BGP path: the network claiming to introduce the addresses to the internet. Hetzner legitimately originated the covering block 162.55.0.0/16. The fraudulent /24 was a more-specific route, meaning it described a smaller slice inside that /16.

Routers use longest-prefix match: of two routes covering an address, the one with more fixed address bits wins. A /24 is longer and more specific than a /16. Wherever both routes propagated, traffic for 162.55.80.0/24 followed the fraudulent /24.

Longest-prefix match chooses the narrower route Router Legitimate covering route162.55.0.0/16 Forged more-specific162.55.80.0/24 wins
The broader /16 stays in the table, but packets for the /24 follow the longer match.

The affected /24 hosted Softaculous software-update endpoints, its client and billing site, and the Virtualizor update endpoint. The attackers obtained a valid TLS certificate in Softaculous’s name and served malicious software updates to affected users. TLS protected the connection to the endpoint clients reached; it did not tell them that BGP had led them to the wrong endpoint.

The event ran intermittently in two waves for about 33 hours, from roughly 20:57 UTC on August 28 until 06:10 UTC on August 30. Hetzner reclaimed the space by announcing the same 162.55.80.0/24 at about 08:44 UTC on August 29. That defensive route was later withdrawn. The attacker returned for a second wave, then finally withdrew around 06:10 UTC on August 30.

Forged /24 appears. Wave 1 begins.

Hetzner announces the same /24 and reclaims traffic.

Hetzner withdraws its /24.

The attacker’s route returns.

The fraudulent route is finally withdrawn.

Why RPKI stamped it Valid

RPKI, the Resource Public Key Infrastructure, lets address holders publish signed routing permissions. A ROA, or Route Origin Authorization, contains three important values: an IP prefix, the origin ASN allowed to announce it, and maxLength, the longest prefix length that permission covers.

The ROA covering 162.55.0.0/16 authorized origin AS24940 with maxLength /24. That did not authorize only one /24. It authorized announcements at every length from /16 through /24 anywhere inside the block. The forged announcement used a /24 and placed AS24940 at the end of its path. Both fields matched.

One ROA opened a nine-length authorization window /16/17/18/19/20/21/22/23/24 FORGED /24 LANDS HERE ROV: VALID
Prefix covered, /24 allowed, AS24940 shown as origin: the route fits the ROA even though the announcement is unauthorized.

Read the bogus announcement like a packet capture

Expand each field. The important clue is not hidden syntax; it is the difference between what ROV checks and what an operator would want to know.

BGP UPDATE · 2026-08-28 20:57 UTCROV VALID
Network Layer Reachability Information162.55.80.0/24

The announced destination is one /24 inside Hetzner’s legitimate 162.55.0.0/16. That more-specific route wins longest-prefix match.

AS path… 6204 62390 24940

Transit AS6204 and AS62390 appear before AS24940. The last value looks like Hetzner’s origin, but it was forged. ROV does not authenticate the earlier path segments.

ROA lookup162.55.0.0/16 · AS24940 · maxLength /24

The /24 sits inside the /16, its length is no longer than /24, and its apparent origin equals AS24940. Every ROV comparison passes.

VerdictVALID

This verdict means “matches the ROA,” not “Hetzner approved this route” and not “the AS path is genuine.”

What route-origin validation checks—and what it does not

ROV, or Route Origin Validation, is defined by RFC 6811. It compares the announced prefix length and the origin ASN with a ROA. In this case, the /24 length was allowed and AS24940 appeared as the origin, so the result was Valid.

ROV does not prove the rest of the AS path is genuine. It also does not prove that the origin network authorized this particular announcement. The word Valid describes two matched fields, not the route’s full legitimacy. That limit is explicit, not an implementation bug.

Keep the layers separateRPKI origin validation can reject routes whose origin or length conflicts with a ROA. It cannot by itself stop an attacker who forges an allowed origin inside an allowed prefix-length window.

What tight maxLength policy looks like

Start with the route you really originate. If you announce 162.55.0.0/16, create a ROA for that /16 with maxLength /16. The prefix length and maxLength are identical, so no more-specific route inherits permission.

If you intentionally deaggregate—split a larger prefix into smaller announcements—create ROAs for the specific prefixes and lengths you actually originate. Do not use a broad maxLength as a shortcut. Compare the ROA inventory with live BGP announcements regularly, especially after address-plan, DDoS, or traffic-engineering changes.

ASPA, Autonomous System Provider Authorization, is the path-side complement: it is designed to describe which providers an AS authorizes, giving validators information about relationships beyond the final origin. It does not make tight ROAs optional.

Four real-world mistakes

  1. Reading Valid as trusted. It means the origin ASN and prefix length match a ROA. It is not an identity check for every AS in the path.
  2. Setting maxLength to /24 “just in case.” On a /16, that opens every length from /16 through /24, even when you announce only the /16.
  3. Tightening ROAs before inventorying deaggregates. A legitimate smaller announcement becomes Invalid if you remove its permission first. Discover what you originate, publish the exact ROAs, then tighten.
  4. Trusting TLS as code integrity. Softaculous had no code signing on its updates, so modified packages could install after traffic reached the attacker. Sign update packages and verify the signature independently of the download connection.

Check your own ROAs this week

Fact-check sourcesThis incident account was checked against MANRS, “Latest BGP Hijack Targets Hosting Software Vendor” (September 2026), and Noction’s “ROA maxLength: From BGP Hijack to Malicious Update.”
Key takeaways

Keep reading