Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset python/PYTHON-LANG-SEC-072 --project .About This Rule
Understanding the vulnerability and how it is detected
paramiko's SSHClient.exec_command() executes a shell command on the remote server via the SSH exec channel. The command is passed to the remote shell (/bin/sh by default) which interprets shell metacharacters. When the command string is constructed from untrusted user input, an attacker can inject shell metacharacters to execute additional commands on the remote host.
The risk pattern is the same as local OS command injection but the impact is remote: the injected commands execute on the SSH server with the SSH user's privileges on that system.
SSH exec_command() sends a single command to the remote shell without an interactive session. Use paramiko's invoke_shell() only when an interactive session is genuinely required, and use exec_command() with validated, sanitized arguments for automation.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Remote Command Injection
Shell metacharacters in user-controlled content injected into exec_command() execute additional commands on the remote SSH server. Semicolons, pipes, backticks, and dollar signs are all interpreted by the remote shell, enabling injection of arbitrary remote commands.
Remote System Compromise
Injected commands execute with the SSH user's privileges on the remote server. If the SSH user has sudo rights or the server runs other sensitive services, command injection can escalate to full remote system compromise.
Lateral Movement
SSH automation scripts that execute commands on multiple servers are particularly dangerous when compromised. Command injection in one server's exec_command() call can affect all servers in the automation pool.
Sensitive Output Capture
If the injected command outputs sensitive data (credentials, private keys, configuration) and stdout is captured, the attacker can extract this data through the command output returned to the Python application.
How to Fix
Recommended remediation steps
- 1Validate all user-controlled values that appear in exec_command() arguments against strict allowlists or regex patterns before use.
- 2Use shlex.quote() to properly quote arguments that must be included in shell commands executed via exec_command().
- 3Prefer a fixed allowlist of pre-defined commands over dynamic command construction; store full commands as constants and look them up by validated name.
- 4Capture and validate the exit code and stderr from exec_command() to detect errors and potential injection attempts.
- 5Use SFTP for file operations instead of exec_command() with cp/mv/cat to eliminate shell involvement entirely.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule detects calls to exec_command() on paramiko SSHClient and Channel objects. All call sites are flagged since exec_command() executes commands on remote systems via a shell, and the command argument requires review to ensure no user-controlled content can inject shell metacharacters.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Python
Paramiko Implicit Host Key Trust (AutoAddPolicy)
paramiko.AutoAddPolicy() and WarningPolicy() automatically accept unknown SSH host keys, enabling man-in-the-middle attacks on SSH connections.
Dangerous subprocess Usage
subprocess calls detected. Ensure command arguments are not user-controlled to prevent OS command injection.
Dangerous os.system() or os.popen() Call
os.system() and os.popen() execute shell commands via /bin/sh, enabling command injection when arguments contain untrusted input.
Frequently Asked Questions
Common questions about Paramiko exec_command() Usage
New feature
Get these findings posted directly on your GitHub pull requests
The Paramiko exec_command() Usage rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.