Gallopsled / Gallopsled/pwntools

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

Open
#2,751 3 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
Python
Stars
13.7k
Forks
1.9k
Avg merge
6d 23h
Merged PRs (30d)
3

Description

## 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`](https://docs.pwntools.com/en/latest/tubes/ssh.html#pwnlib.tubes.ssh.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

Contributor guide

Open the contributing guide

Research direction

Start with the ssh.process and ssh.system documentation and reproduce the environment examples from the issue, especially with an empty env dict. Trace how each entry point handles env and compare that behavior with the documented contract. Done means the intended behavior is established and the implementation or documentation consistently reflects it, with regression coverage where appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.