#2751·pwntools

Question about inconsistent `env` behavior between `ssh.process` and `ssh.system`

Author: enihsyouCreated Jun 26, 2026Updated Jun 26, 2026
Labelsquestion

Description

There is an inconsistency on how the env parameter is handled between ssh.process and ssh.system.

According to the documentation for ssh.process:

env (dict) – Environment variables to add to the environment.

However, in practice, ssh.process replaces the remote environment if a dictionary is provided, whereas ssh.system updates to the existing environment (via shell export).

Steps to Reproduce / Examples

1. ssh.process (Behavior: Replace)

When passing an empty dict env={}, the entire environment is cleared instead of just "adding nothing".

python
>>> s.process(['/usr/bin/env']).recvall()
b'PATH=...'
>>> s.process(['/usr/bin/env'], env={}).recvall()
b'' # All original environment variables are gone.
>>> s.process(['/usr/bin/env'], env={'A': 'a'}).recvall()
b'A=a\n' # no PATH, etc

2. ssh.system (Behavior: Update)

ssh.system executes commands in a shell context, so the env dict updates the existing environment.

python
# The original environment variables (like PATH, USER, etc.) are still preserved
>>> s.system('env', env={'MY_VAR': 'value'}).recvall()
b'PATH=...\nUSER=...\nMY_VAR=value\n...'

Impact & Questions

This inconsistency makes it confusing to manage remote environments. If a user wants to add an environment variable to ssh.process without wiping out defaults (like PATH), they currently have to manually fetch the remote environment first (e.g., via ssh.system('env')) and merge it.

  1. What is the intended design choice here? Should ssh.process actually add (update) the environment to match the documentation and ssh.system's behavior?
  2. If ssh.process replacing the environment is the intended behavior, should the documentation be updated to clarify this (e.g., changing "add to" to "replace")?

Environment

  • Pwntools version: 4.15.0