Skip to main content

Free 30-min security demo Book Now

Offensive360 Offensive360
ZeroDays CVE-2026-71965
High CVE-2026-71965 CVSS 8.8 CyberPanel Python

CyberPanel Remote Backup SSH Key Injection

CVE-2026-71965: Authenticated RCE in CyberPanel 2.4.3 lets attackers write arbitrary SSH keys to /root/.ssh/authorized_keys via the remote backup feature.

Offensive360 Research Team
Affects: <= 2.4.3
Source Code View Patch

Overview

CVE-2026-71965 is an authenticated remote code execution vulnerability in CyberPanel 2.4.3, a widely deployed open-source web hosting control panel built on OpenLiteSpeed. The flaw resides in the remote backup feature, which initiates SSH connections to user-supplied remote servers. Because CyberPanel unconditionally trusts and persists the SSH host key returned by the remote server during the initial connection handshake, an attacker controlling a malicious server can inject an arbitrary SSH public key directly into /root/.ssh/authorized_keys on the CyberPanel host. The result is persistent, password-free root access over SSH — the highest possible level of system compromise.

The vulnerability was identified by security researchers and is documented in the project’s commit history. CyberPanel is a popular choice among small-to-medium hosting providers and managed service resellers, making the exposure surface significant. Any authenticated user — including those with limited panel roles that have access to the backup configuration UI — can exploit this flaw, meaning the attack does not require administrator credentials, only a valid account.

The fix was introduced in commit eca0c3c, which enforces strict host key verification before any key material is written to the filesystem. All CyberPanel deployments running version 2.4.3 or earlier should treat this as a critical remediation priority given the trivial exploitation path and the severity of the resulting access.

Technical Analysis

The root cause is a classic TOFU (Trust On First Use) SSH host key verification failure combined with an insecure write path. When a user configures a remote backup destination, CyberPanel constructs an SSH connection to the supplied hostname or IP address using Paramiko, Python’s SSH library. The vulnerable code invokes AutoAddPolicy — Paramiko’s built-in policy that silently accepts and records any host key presented by the remote server — rather than requiring the operator to pre-verify and store a known-good fingerprint.

The critical secondary failure is where the accepted key material ends up. CyberPanel’s backup module, running as root, subsequently writes the “trusted” host key or known-hosts entry in a code path that also has write access to /root/.ssh/authorized_keys. A malicious server can present a crafted host key response that, after the panel’s post-processing, results in an attacker-controlled public key being appended to the root user’s authorized keys file.

Vulnerable code pattern (simplified representative example):

import paramiko
import os

def connect_remote_backup(hostname, username, port=22):
    client = paramiko.SSHClient()
    # VULNERABLE: AutoAddPolicy blindly accepts any host key
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(hostname, port=port, username=username)
    return client

def sync_ssh_keys(remote_host, backup_user):
    client = connect_remote_backup(remote_host, backup_user)
    # The host key accepted above is then written into the root
    # authorized_keys file as part of backup trust establishment
    host_key = client.get_transport().get_remote_server_key()
    key_entry = f"{remote_host} {host_key.get_name()} {host_key.get_base64()}\n"
    authorized_keys_path = "/root/.ssh/authorized_keys"
    with open(authorized_keys_path, "a") as f:
        f.write(key_entry)  # VULNERABLE: attacker-controlled key written as root

The compound failure here is twofold. First, AutoAddPolicy removes any cryptographic trust anchor — the entire security model of SSH host verification is bypassed. Second, the code conflates the SSH known-hosts concept (server identity verification) with the authorized-keys concept (client authentication), writing what is effectively attacker-supplied key material into the file that governs root login authorization. An attacker simply stands up a server that returns a crafted public key as its host key, points CyberPanel’s backup feature at it, and their corresponding private key immediately grants root SSH access to the victim host.

The CVSS 8.8 score reflects the authenticated pre-condition (requiring a valid panel account) as the primary mitigating factor. The attack complexity is low, no special privileges beyond a basic account are needed, and user interaction is limited to the attacker submitting a backup configuration form.

Impact

A successful exploit grants the attacker an interactive root shell on the underlying server via standard SSH — no web shell, no further pivoting required. From this position, an attacker can exfiltrate all hosted website data, databases, SSL private keys, and email content managed by the panel; deploy persistent backdoors or ransomware; modify DNS records and SSL certificates to facilitate further attacks against hosted domains; pivot into connected internal networks; and completely destroy the host environment, including all tenant data.

The persistence mechanism is notable: even if the CyberPanel vulnerability is patched after exploitation, the injected key in /root/.ssh/authorized_keys remains active until explicitly removed. Defenders must treat any exploitation as requiring a full authorized-keys audit in addition to software patching.

Organizations running CyberPanel in multi-tenant hosting environments face compounded risk. A single low-privilege reseller account could be the entry point for compromising every tenant on the server.

How to Fix It

Upgrade CyberPanel to a version incorporating commit eca0c3c or later. There is no safe configuration workaround short of disabling the remote backup feature entirely.

Corrected code pattern — enforce strict host key verification against a pre-established known-hosts file, and never write host key material into authorized_keys:

import paramiko
import os

KNOWN_HOSTS_PATH = "/etc/cyberpanel/known_hosts"

def connect_remote_backup(hostname, username, port=22):
    client = paramiko.SSHClient()
    # FIXED: Reject connections to hosts not in the known-hosts file
    client.set_missing_host_key_policy(paramiko.RejectPolicy())
    if os.path.exists(KNOWN_HOSTS_PATH):
        client.load_host_keys(KNOWN_HOSTS_PATH)
    # Raises paramiko.SSHException if host key is unknown or mismatched
    client.connect(hostname, port=port, username=username)
    return client

def verify_and_add_known_host(hostname, expected_fingerprint, port=22):
    """
    Separate, explicit administrator workflow to add a trusted backup host.
    Fingerprint must be verified out-of-band before calling this function.
    """
    transport = paramiko.Transport((hostname, port))
    transport.connect()
    host_key = transport.get_remote_server_key()
    transport.close()
    actual_fp = host_key.get_fingerprint().hex()
    if actual_fp != expected_fingerprint:
        raise ValueError(f"Fingerprint mismatch: got {actual_fp}")
    # Write only to known_hosts, never to authorized_keys
    with open(KNOWN_HOSTS_PATH, "a") as f:
        f.write(f"{hostname} {host_key.get_name()} {host_key.get_base64()}\n")

Additionally, /root/.ssh/authorized_keys should never be writable by application-level code. Apply filesystem-level controls and audit this file regularly as part of your hardening baseline.

Our Take

This vulnerability represents a category of flaw we see repeatedly in control panel and automation software: the SSH AutoAddPolicy anti-pattern. Developers reach for it during prototyping because it eliminates the friction of host key management, then it ships to production unchanged. The Paramiko documentation itself warns against using AutoAddPolicy in anything other than a development context, yet it continues to appear in production codebases.

What makes this instance particularly damaging is the write-path confusion — treating the remote backup trust relationship as something that needs to manifest in authorized_keys. These are architecturally distinct concepts, and collapsing them creates a direct privilege escalation primitive. Enterprises running hosting infrastructure should treat any application that writes to authorized_keys programmatically as a high-risk surface requiring explicit security review.

For developers: enumerate every location in your codebase that opens an SSH connection and audit the host key policy. For security teams: include SSH client configuration and authorized_keys write paths in your threat modeling for any server-side application running with elevated privileges.

Detection with SAST

SAST tooling identifies this vulnerability class by flagging the use of paramiko.AutoAddPolicy() as a high-confidence security finding under CWE-295 (Improper Certificate Validation) — which encompasses improper validation of cryptographic identity in transport-layer protocols, including SSH host keys.

At Offensive360, our SAST engine specifically flags the following patterns in Python codebases:

  • Any call to client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) or paramiko.WarningPolicy()
  • SSH client instantiation where no explicit host key policy is set (defaulting to AutoAddPolicy in some Paramiko versions)
  • Data flows where SSH transport key material (get_remote_server_key(), get_host_key()) is written to files in ~/.ssh/ or /root/.ssh/
  • File write operations targeting paths matching authorized_keys from code running with elevated privileges

The secondary write-path issue maps to CWE-732 (Incorrect Permission Assignment for Critical Resource) and CWE-20 (Improper Input Validation) — the application fails to validate that attacker-influenced data (the remote server’s presented key) is appropriate to persist in a security-critical file.

DAST coverage for this class requires an active test harness that can impersonate a malicious SSH server and observe whether the host key is accepted and persisted. Static analysis alone cannot fully exercise the runtime data flow without dynamic validation of the write behavior.

References

#RCE #SSH #Privilege Escalation #Injection

Detect this vulnerability class in your codebase

Offensive360 SAST scans your source code for CVE-2026-71965-class vulnerabilities and thousands of other patterns — across 60+ languages.