Summary:
A recently unearthed vulnerability—CVE-2026-35386—affects OpenSSH versions before 10.3 when used with some non-default configurations. If you accept untrusted usernames on the command line, and are using % placeholders in your ssh_config, attackers can slip in shell metacharacters to run arbitrary commands on your system. This walkthrough explains what's going on and how an exploit could work.
What’s the Issue?
OpenSSH is the go-to secure shell tool for system administrators everywhere. Usually, it’s very good at keeping things safe, but if you customize your setup and process usernames directly with shell, things can get tricky.
In some setups, admins use placeholders (like %u for username) in their ~/.ssh/config or /etc/ssh/ssh_config files for scripting flexibility. For example:
Host *
HostName %h
User %u
Unfortunately, if you're building SSH commands using untrusted (user-supplied) usernames and include them directly in a shell command, attackers can add shell tricks—like ; or &—to their username and cause the shell to run whatever commands they like.
Important Note:
If you don't use % expansions, or never put untrusted input in the username spot, you're safe. This vulnerability only bites in specific, non-standard configurations.
A Practical Example
Let's say you have a shell script that builds and executes an SSH command, where the username is supplied from the outside (like a web script or user input):
#!/bin/bash
TARGET_HOST="server.example.com"
USER_INPUT="$1" # Let's pretend this is untrusted
# You use ssh_config entries with % substitutions
ssh "$USER_INPUT@$TARGET_HOST"
And in ~/.ssh/config you have
Host server.example.com
HostName 192..2.123
User %u
If the input from a user (say, through a web form) is
bob;touch /tmp/pwned;#
When OpenSSH expands %u, and the shell builds the command, the resolved command line will be
ssh "bob;touch /tmp/pwned;#@server.example.com"
If the command line is not carefully sanitized, the shell interprets ; as a command separator and will execute touch /tmp/pwned as the local user running the script—not as a remote command! Now the attacker (bob) left their marker file, confirming they have some code execution power.
Customized ssh_config using % for username or other fields
- The username in the SSH command is untrusted (i.e., from public input, not from a trusted source)
- The SSH command is built/executed using a shell without proper input sanitization
Suppose you have
#!/bin/bash
echo "Connecting as $1"
ssh "$1@myhost"
Running as
$ ./safessh "bob;echo HACKED > /tmp/hacked;"
If ssh is invoked in a subshell where parameters are not sanitized, the injected echo command runs on the local system.
Never use untrusted input for username fields in commands
- Avoid shell interpolation; use argument arrays in scripts (e.g., ssh "$username@$hostname" in Bash with sanitized input)
What Makes This CVE Dangerous?
While it's not a default misconfiguration, automated systems, provisioning tools, or web frontends automating SSH tasks are routinely built by well-meaning admins. Injecting shell code via a username is easily overlooked, particularly when leveraging % for DRY (Don’t Repeat Yourself) configs. Privilege escalation or theft of secrets via command injection is the likely risk.
Original References
- OpenSSH Release Notes
- CVE-2026-35386 at MITRE (will be available soon)
- How SSH config patterns work (official man page)
- OpenSSH GitHub Repository
Closing Thoughts
CVE-2026-35386 is a stark reminder: _never trust untrusted input_. Always sanitize any parameters that wind up on a shell command line, especially in scripts that interact with SSH and use dynamic config elements like %u. Update OpenSSH to at least version 10.3 and audit your configurations and scripts—before someone else finds a way in.
Stay Safe!
If you have questions about this CVE or want to check your configs, drop a comment or review the references above.
*This article is original content by SecureNerd for hands-on sysadmins dealing with real-life infosec concerns in 2024.*
Timeline
Published on: 04/02/2026 16:44:27 UTC
Last modified on: 04/27/2026 14:03:07 UTC