← Back to Feed CACHED · 2026-11-01 12:41:36 · CACHE_KEY CVE-2026-120197
CVE-2026-120197 · CWE-77 · Disclosed 2026-11-01

WAVLINK WL-WN530HG4B wapi.cgi port_forward command injection via Name parameter

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A router's port-forwarding form is a root shell with a login screen

The vulnerable function port_forward in /cgi-bin/wapi.cgi on WAVLINK WL-WN530HG4B firmware M_V260724 passes the Name argument to a shell command without sanitizing shell metacharacters. An authenticated remote user can inject OS commands with the router's privileges, leading to complete device takeover. The issue is CWE-77 (command injection) and has a public exploit.

The vendor's CRITICAL 9.9 CVSS score is technically plausible from the impact side, but it assumes an authenticated attacker can reach the management interface. In real enterprise deployments this WAVLINK device is usually a small-office/home router, not a data-center edge appliance, so the practical severity is one notch lower.

"Post-auth command injection in a SOHO router; patch immediately if it's your network edge."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Reach the WAVLINK web management interface

The attacker locates a device exposing /cgi-bin/wapi.cgi over the network, either from the internet if remote management is enabled or from the local LAN. Shodan/Censys can fingerprint WAVLINK web interfaces using server headers or page content.
Conditions required:
  • Remote management must be enabled for WAN access, or the attacker already has LAN access
  • Device firmware is M_V260724 or another affected build
Where this breaks in practice:
  • WAVLINK ships with WAN-side administration disabled by default
  • SOHO devices are often behind a NAT with no port forwarding to the admin panel
Detection/coverage: Shodan/Censys banners can identify WAVLINK devices; network scans can detect exposed TCP 80/443.
STEP 02

Authenticate to the management console

The attacker logs in with low-privilege credentials. Many WAVLINK units still use default credentials such as admin/admin, or the password may be cracked from a weak dictionary.
Conditions required:
  • Attacker holds valid credentials, either default, guessed, or captured
  • No login rate limiting or lockout is enforced
Where this breaks in practice:
  • Changed default passwords block many opportunistic attacks
  • Some firmware builds throttle repeated login attempts
Detection/coverage: Web access logs show authentication events; SIEM can alert on multiple failed logins.
STEP 03

Inject a command through the port_forward Name parameter

The attacker sends an HTTP request to /cgi-bin/wapi.cgi invoking the port_forward function with a malicious Name value containing shell metacharacters such as ;, |, or &&. The unsanitized value is passed to a system command, executing the attacker's payload on the router.
Conditions required:
  • The target parameter Name is not sanitized or filtered
  • The request must include a valid session token or cookie
Where this breaks in practice:
  • A WAF in front of the admin panel could flag the injection pattern, but most SOHO deployments have no WAF
Detection/coverage: Network IPS/IDS signatures for command injection in HTTP parameters may catch the attempt; host-based detection is absent on the router.
STEP 04

Gain root shell on the router

The injected command executes with the privileges of the web server, typically root on WAVLINK firmware. The attacker can start a reverse shell, add a user, or write persistent startup scripts.
Conditions required:
  • Command execution must succeed; the payload must be compatible with the router's busybox environment
Where this breaks in practice:
  • Limited writable storage and firmware restrictions can complicate persistence, but one-shot commands are still effective for compromise
Detection/coverage: Firmware integrity monitoring is rare on SOHO routers; network traffic analysis may spot reverse shells.
STEP 05

Pivot into the LAN or manipulate traffic

With root on the gateway, the attacker can change DNS/DHCP settings, redirect traffic, add port forwards, capture credentials, or use the router as a jump host into internal systems.
Conditions required:
  • The WAVLINK device must be acting as the network's default gateway or DNS server for maximum impact
Where this breaks in practice:
  • If the router is only an access point or isolated lab device, impact is limited
Detection/coverage: SIEM may detect rogue DNS responses or unexpected port-forward changes; network flow monitoring can identify lateral traffic from the router.
03 · Compensating Control

1
HIGH 7.8→MEDIUM 5.5
SEVERITY REDUCED
Disable WAN-side administration and restrict management to a trusted LAN/VLAN — This removes the remote-reachability precondition. If the attacker cannot reach /cgi-bin/wapi.cgi from the internet, the attack path requires LAN access. Deploy within 30 days per noisgate mitigation SLA.
2
HIGH 7.8→MEDIUM 5.0
SEVERITY REDUCED
Change all default credentials and enforce strong admin passwords — The command injection requires authentication; removing default or weak credentials blocks many opportunistic attacks. Deploy within 30 days per noisgate mitigation SLA.
3
HIGH 7.8→HIGH 7.0
Put a WAF or IPS in front of the router admin interface — A signature-based control can detect and block command injection patterns in the Name parameter. Deploy within 30 days if remote management must remain enabled.
4
HIGH 7.8→IGNORE 0.0
SEVERITY REDUCED
Apply the WAVLINK firmware patch when released — The definitive fix sanitizes the port_forward Name parameter or removes the command execution sink. Schedule within 180 days per noisgate remediation SLA once a fixed firmware is available.
5
HIGH 7.8→MEDIUM 5.0
SEVERITY REDUCED
Segment the management interface from guest or user wireless networks — Limits reachability to an isolated management VLAN, reducing the population that can attempt authentication. Deploy within 30 days per noisgate mitigation SLA.
What doesn't work
  • Installing AV/EDR on Windows or Linux hosts does not detect the command injection because the vulnerable code runs on the router's firmware.
  • Changing the Wi-Fi SSID or Wi-Fi password does not restrict access to the router's web management interface.
  • Relying on HTTPS alone does not prevent command injection; it only encrypts the malicious request in transit.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNot listed in CISA KEV as of 2026-11-01; no named mass exploitation campaign confirmed.
Proof-of-concept availabilityPublic exploit exists per the official CVE record; likely mirrored on VulDB and GitHub.
EPSSEPSS score not published for this CVE yet; public PoC raises the probability of opportunistic scanning.
KEV statusNot listed in CISA Known Exploited Vulnerabilities catalog.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — 9.9 Critical; changed scope reflects router-to-LAN compromise.
Affected versionWL-WN530HG4B firmware M_V260724; earlier builds may be affected but not confirmed.
Fixed versionNone identified at disclosure; vendor was contacted early but no patch announced in the record.
Exposure dataShodan/Censys queries for WAVLINK banners can expose devices; enterprise prevalence is low because the device is SOHO class.
Disclosed2026-11-01
Reporting researcherNot named in the official CVE record.

Sources.

  1. NVD
  2. CVE.org
  3. WAVLINK support
  4. CWE-77
  5. CISA KEV
  6. FIRST EPSS
05 · The Call

Final Verdict
↓ DOWNGRADED to HIGH (7.8/10)

Why this verdict

  • Vendor baseline is 9.9 Critical, but that assumes an authenticated attacker can reach the management interface over the network.
  • Role multiplier: If a WAVLINK WL-WN530HG4B is used as a small-business perimeter router, successful command injection yields root on the gateway and a pivot into the LAN — this floors the verdict at HIGH; however, WAVLINK is consumer/SOHO-class and enterprise installed base is likely <1%, so CRITICAL is not justified.
  • Exposure friction: WAN-side administration is typically disabled by default, so the vulnerable endpoint is usually reachable only from the LAN or after explicit remote management enablement.
  • Public exploit: A public PoC exists, so any reachable device with default or weak credentials is immediately exploitable without user interaction.

Why not higher?

Not CRITICAL because the vulnerability requires low-privilege authentication and the device is a SOHO router with a small enterprise footprint. Most WAVLINK units are not deployed as enterprise perimeter gateways, and remote management is not exposed by default.

Why not lower?

Not MEDIUM or lower because command execution on a network gateway is a high-impact outcome: root on the router, DNS/DHCP manipulation, traffic interception, and a pivot point into the LAN. The existence of a public exploit removes the need for research and lowers the barrier for attackers who can reach the device.

06 · Verification

Crowdsourced verification payload.

Run from an auditor workstation that can reach the target router's management interface. Invoke: python3 check_CVE-2026-120197.py <router_ip_or_host> --user admin --password <password>. Requires network access to the admin panel and valid low-privilege credentials. If credentials are unknown, the script reports UNKNOWN unless the endpoint is reachable anonymously.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
'''CVE-2026-120197 check for WAVLINK WL-WN530HG4B M_V260724
Sends a harmless time-based command injection to /cgi-bin/wapi.cgi and
reports VULNERABLE if the injected sleep delays the response.
'''
import argparse
import sys
import time
import requests
from urllib.parse import urljoin


def log(message):
    print(f'[!] {message}', file=sys.stderr)


def main():
    parser = argparse.ArgumentParser(description='Check CVE-2026-120197')
    parser.add_argument('target', help='Router URL, e.g. http://192.168.10.1')
    parser.add_argument('--user', default='admin', help='Admin username (default: admin)')
    parser.add_argument('--password', required=True, help='Admin password')
    parser.add_argument('--timeout', type=int, default=10, help='Request timeout in seconds')
    args = parser.parse_args()

    base = args.target.rstrip('/')
    session = requests.Session()
    session.headers.update({'User-Agent': 'CVE-2026-120197-check/1.0'})

    # Attempt common WAVLINK login endpoint. Adjust if your firmware uses a different path.
    login_data = {'username': args.user, 'password': args.password}
    try:
        r = session.post(urljoin(base, '/cgi-bin/login.cgi'), data=login_data, timeout=args.timeout, verify=False)
        if r.status_code >= 400 or 'error' in r.text.lower():
            log('Login failed or endpoint not found; cannot confirm authenticated access.')
            print('UNKNOWN')
            return 1
    except requests.RequestException as e:
        log(f'Login request failed: {e}')
        print('UNKNOWN')
        return 1

    # Time-based command injection through the Name parameter.
    # The command 'sleep 5' is harmless but produces a 5-second delay if vulnerable.
    malicious_name = 'test; sleep 5; #'
    data = {
        'action': 'port_forward',
        'Name': malicious_name
    }
    url = urljoin(base, '/cgi-bin/wapi.cgi')
    try:
        start = time.time()
        r = session.post(url, data=data, timeout=args.timeout, verify=False)
        elapsed = time.time() - start
    except requests.RequestException as e:
        log(f'Injection request failed: {e}')
        print('UNKNOWN')
        return 1

    if elapsed >= 4.0:
        print('VULNERABLE')
        return 0
    elif r.status_code == 200:
        print('PATCHED')
        return 0
    else:
        print('UNKNOWN')
        return 1


if __name__ == '__main__':
    sys.exit(main())