CVE-2026-53422
Executive Summary
CVE-2026-53422 is a low-severity (CVSS 2.3) Observable Response Discrepancy vulnerability in the Erlang OTP SSH ssh_sftpd module. An authenticated SFTP user can exploit a canonicalization flaw in the SSH_FXP_REALPATH handler to determine whether files and directories exist outside the configured SFTP root directory, creating a filesystem path-existence oracle. This information disclosure alone does not grant file content access or write privileges, but it can significantly aid reconnaissance for subsequent attacks against the host system or adjacent services.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vulnerability Mechanism
The root cause lies in the inconsistent path handling within the ssh_sftpd module, specifically in lib/ssh/src/ssh_sftpd.erl. Every SFTP operation handler — including OPEN, STAT, OPENDIR, and REMOVE — invokes relate_file_name/3 with Canonicalize=true, which normalizes the requested path before validating it against the configured root directory using is_within_root/2. However, the SSH_FXP_REALPATH handler (implemented in handle_op/4) calls relate_file_name/3 with Canonicalize=false.
This discrepancy means that when a client sends a REALPATH request containing .. traversal components, the path is not resolved to its canonical form prior to the root containment check. The is_within_root/2 function performs only a syntactic prefix check against the un-resolved path string, allowing paths such as ../../../etc/shadow to pass validation because the lexical check cannot see that the .. components escape the root directory.
Path Escape and Symlink Resolution
After passing the containment check, the un-canonicalized path enters resolve_symlinks/2. This function walks the directory tree component-by-component and issues read_link() system calls on each component to resolve symbolic links. Crucially, this resolution happens above the configured root boundary — the function will traverse up the real filesystem hierarchy, following symlinks that exist outside the SFTP jail.
The attacker does not need a pre-existing symlink to abuse this behavior. The traversal itself (../../..) directly escapes the root directory and resolve_symlinks/2 will operate on paths such as /home/user, /etc, /var — whatever the traversal depth reaches.
Filesystem Oracle
The exploitation vector is an information disclosure side-channel. The server's response to SSH_FXP_REALPATH differs based on whether the target path exists:
- Path exists: Server returns
SSH_FXP_NAME(response packet type 104). - Path does not exist: Server returns
SSH_FX_NO_SUCH_FILE(status code 2 within anSSH_FXP_STATUSpacket, type 101).
This binary response differential allows an authenticated SFTP client to enumerate the existence of any path on the host filesystem, including:
- Sensitive files (
/etc/shadow,/root/.ssh/id_rsa) - Mount points (
/proc,/sys,/dev/shm) - Home directories (
/home/user1,/home/user2) - Application data (
/opt/app/config.ini,/var/lib/mysql)
Attack Surface
- Attack Vector: Network (AV:N)
- Attack Complexity: High (AC:H) — requires authenticated SFTP access; the traversal path must be crafted to avoid triggering other sanity checks
- Privileges Required: Low (PR:L) — any valid SFTP account
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U) — the oracle leaks information about the host filesystem but does not directly impact other security contexts
The attack complexity is rated High because the attacker needs to know (or guess) absolute paths on the host filesystem, and the traversal depth must be calibrated correctly to reach the target from the configured root.
Exploitation Scenarios
Step-by-Step Attack Chain
Phase 1: Reconnaissance The attacker first identifies an Erlang/OTP SSH server with SFTP enabled. This can be done by:
- Scanning for TCP port 22 or a custom SSH port.
- Attempting an SSH connection with the
sftpsubsystem request (subsystem "sftp"). - Observing the SSH banner to fingerprint Erlang/OTP (
SSH-2.0-Erlangin some configurations).
Phase 2: Authentication The attacker obtains valid SFTP credentials through phishing, credential stuffing, or by compromising a low-privilege account on the Erlang application.
Phase 3: REALPATH Traversal Trigger
Using the SFTP protocol directly (e.g., via the paramiko Python library or a custom packet builder), the attacker sends an SSH_FXP_REALPATH packet (type 16) with a crafted path. A sample request sequence:
- Open SFTP channel within the SSH session.
- Send
SSH_FXP_INIT(type 1) to initialize the SFTP session. - Send
SSH_FXP_REALPATH(type 16) with payload:- Request ID (4 bytes):
0x00000001 - Path (string):
../../../etc/
- Request ID (4 bytes):
- Parse the server's response.
Phase 4: Filesystem Enumeration
The attacker repeats this process, varying the traversal depth and target suffix. Example probe sequence targeting /etc/shadow from a root of /home/sftpuser:
- Depth 0:
/home/sftpuser/../../../etc/shadow→ resolves to/etc/shadow - Depth 1:
/home/sftpuser/../../etc/shadow→ resolves to/var/etc/shadow(or fails) - Calibrate: adjust
..count until the server returnsSSH_FXP_NAMEfor known-existing paths.
Once calibrated, the attacker builds a dictionary of candidate paths and probes each. Each probe is a single round-trip over the SFTP channel — enumeration of a few hundred paths takes seconds.
Phase 5: Post-Exploitation Intelligence The attacker now possesses a map of the host filesystem, revealing:
- User accounts and home directory names.
- Installed applications and their configuration locations.
- Database availability (e.g., presence of
/var/lib/mysql). - Container/jail environment details (presence of
/proc,/sys).
This intelligence is packaged for follow-on attacks. If other vulnerabilities exist in the Erlang application or adjacent services, the attacker uses the filesystem map to target them precisely.
Limitations (parenthetical note): This vulnerability requires authenticated SFTP access and leaks only path-existence data — no file contents, no write access, and no direct code execution.
Impact Assessment
| Dimension | Assessment |
|---|---|
| Confidentiality | Low — Leaks only file/directory existence, not contents |
| Integrity | None — No write or modify capability |
| Availability | None — No denial-of-service vector |
| Attack Complexity | High — Requires authenticated session and careful traversal calibration |
| Business Impact | Moderate — Facilitates targeted follow-on attacks; leaks system topology |
The CVSS vector CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N scores this at 2.3 (Low). The low score reflects that the confidentiality impact is limited to existence checks. However, the blast radius extends beyond the SFTP root — the host filesystem's entire layout becomes enumerable. In environments where Erlang/OTP SFTP serves as an integration point (e.g., RabbitMQ nodes, distributed Erlang clusters, MQTT brokers with SFTP file transfer), the leaked topology may expose:
- Erlang cookie file locations (
/etc/erlang.cookie,~/.erlang.cookie). - Distributed Erlang node names and EPMD port configurations.
- Cluster peer discovery via home directory enumeration.
The EPSS score of 0.00262 (17.9th percentile) indicates current exploit activity is low, but automated scanning for this issue is plausible given the straightforward protocol interaction.
Detection Guidance
Sigma Rule
title: Detect Erlang SFTP REALPATH Traversal Attempts
id: 6a1c8b3e-9d42-4f12-8a3e-5d7c9b1f2a44
status: experimental
description: Detects SSH_FXP_REALPATH requests containing directory traversal sequences sent to an Erlang/OTP SFTP server.
logsource:
category: application
product: erlang_sftp
detection:
selection:
sftp_opcode: "REALPATH"
path|contains:
- "../"
- "..\\"
path|re:
- "^[.]{2}/[^/]"
condition: selection
fields:
- client_ip
- username
- path
level: medium
falsepositives:
- Legitimate SFTP clients occasionally resolve paths with single ".." for navigation within expected bounds
tags:
- cve.2026.53422
- attack.discovery
- attack.t1083
YARA Rule
rule Erlang_SFTP_REALPATH_Traversal
{
meta:
author = "valtersit.com Threat Intel"
description = "Detect SSH_FXP_REALPATH packets containing traversal sequences targeting CVE-2026-53422"
cve = "CVE-2026-53422"
date = "2026-01-15"
score = 60
strings:
$opcode = { 10 00 00 00 } // SSH_FXP_REALPATH (type 16 = 0x10)
$traversal1 = "../"
$traversal2 = "../../"
$traversal3 = "..\\"
condition:
$opcode at 0 and (any of ($traversal*))
}
Note: This YARA rule is designed for PCAP payload inspection (SSH binary packets may be encrypted; use this on SFTP subsystem logging where the raw channel data is available).
Suricata IDS Rule
alert tcp any any -> any 22 (msg:"ET POLICY Erlang SFTP REALPATH Traversal CVE-2026-53422"; flow:to_server,established; content:"SSH-2.0-"; nocase; content:"REALPATH"; nocase; distance:0; content:"../"; nocase; reference:cve,2026-53422; classtype:attempted-recon; sid:2026034; rev:1;)
Note: SSH traffic is encrypted end-to-end. This signature detects the SFTP subsystem negotiation and initial SSH banner, not the post-encryption payload. For reliable detection on encrypted traffic, combine this with SSH server-side logging integration (filebeat/auditd).
Elastic Detection
sequence by sftp.server, sftp.user with maxspan=5m
[any where process.name : "beam.smp" and process.args : "*ssh_sftpd*"]
[file where file.operation : "readlink" and file.path : ("/etc/*", "/var/*", "/usr/*", "/root/*")
and not file.path : (sftp.root + "/*")]
Alternatively, for log-based detection where SFTP request logs are captured:
any where sfpt.request_type == "SSH_FXP_REALPATH"
and sftp.path matches ".../.../.../"
Splunk SPL Query
index=erlang_sftp sourcetype=ssh_sftpd
| where like(path, "%../%")
| stats count by client_ip, user, path, _time
| eval traversal_depth = length(../)
Or for network-level:
index=netflow sourcetype=ssh
| stats count by src_ip, dest_ip, dest_port
| where dest_port == 22
| join dest_ip [ search index=ids sourcetype=suricata signature="Erlang SFTP REALPATH Traversal"]
| table _time, src_ip, dest_ip, user
Wazuh OSSEC Rule
<group name="erlang_sftp,">
<rule id="100234" level="8">
<decoded_as>json</decoded_as>
<field name="module">ssh_sftpd</field>
<field name="request_type">REALPATH</field>
<regex>\.\./</regex>
<description>Erlang SFTP REALPATH traversal attempt detected (CVE-2026-53422)</description>
<mitre>
<id>T1083</id>
<description>File and Directory Discovery</description>
</mitre>
<group>attacks.discovery</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 2/4 — CLAIMED (single source claims patch, not independently confirmed)
Immediate Mitigations
- OS-level chroot: Run the Erlang VM (beam.smp) within a chroot jail or container (Docker, systemd-nspawn) that isolates the application from the host filesystem. This eliminates the reliance on the application-level root option.
- Network restriction: Ensure the SFTP port is not reachable from untrusted networks. Apply firewall ACLs to restrict SFTP access to known, trusted IP ranges.
- Data minimization: Avoid placing sensitive files in paths whose existence could be probed. If possible, run the SFTP server on a dedicated VM or container.
Patch/Upgrade Steps
- Upgrade Erlang/OTP to the latest stable release. The fix modifies
relate_file_name/3inssh_sftpd.erlto passCanonicalize=trueon all path types, including REALPATH. - If using a package manager:
sudo apt update && sudo apt upgrade erlang-ssh(Debian/Ubuntu) orbrew upgrade erlang(macOS). - Verify the patched version by checking
erl -eval 'io:format("~s~n", [erlang:system_info(otp_release)])'.
- Upgrade Erlang/OTP to the latest stable release. The fix modifies
Long-term Hardening
- Move SFTP services to dedicated, minimal containers with no host filesystem access.
- Implement FIM (File Integrity Monitoring) on the SFTP root and critical system paths to detect enumeration probes.
- Monitor SFTP protocol-level logs for unusual
REALPATHrequest patterns. - Apply the principle of least privilege — SFTP users should have dedicated, isolated roots with no shared or sensitive data.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-53422
- OSV Advisory: https://osv.dev/vulnerability/CVE-2026-53422 (contains patch references)
- Erlang/OTP Security Announcements: https://www.erlang.org/security (vendor announcements and patch availability)
- Erlang source code reference: https://github.com/erlang/otp/blob/master/lib/ssh/src/ssh_sftpd.erl (for verification of fixed code)
- CWE-204 Reference: https://cwe.mitre.org/data/definitions/204.html
Threat Actor Activity: No known in-the-wild exploitation has been publicly documented. The EPSS score (0.00262, 17.9% percentile) and absence from CISA KEV indicate low exploit activity. No specific threat actor campaigns have been attributed to this vulnerability as of the report date.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.