#2364·fabric

Bug: Command injection via unsanitized env vars when inline_env=True

Author: themavikCreated Mar 19, 2026Updated Aug 10, 2026
LabelsBugConnection

Bug Description

In fabric/runners.py, when inline_env=True (default since Fabric 3.0), env keys and values are concatenated directly into a shell command string without any escaping. This allows arbitrary command execution via crafted env values.

Code Location

fabric/runners.py, lines ~67-73:

python
parameters = " ".join(
    ["{}={}".format(k, v) for k, v in sorted(env.items())]
)
command = "export {} && {}".format(parameters, command)

Reproduction

python
from fabric import Connection
c = Connection("localhost")
c.run("echo hello", env={"X": "a; echo INJECTED #"})
# Executes: export X=a; echo INJECTED # && echo hello
# Output includes "INJECTED" — arbitrary command executed

Impact

Any code path that passes user-controlled or untrusted data into the env parameter of run(), sudo(), or local() is vulnerable to shell command injection.

The code itself has a TODO acknowledging this: "escaping, if we can find a FOOLPROOF THIRD PARTY METHOD for doing so!"

Suggested Fix

Use shlex.quote() for both keys and values:

python
parameters = " ".join(
    ["{}={}".format(shlex.quote(k), shlex.quote(v)) for k, v in sorted(env.items())]
)

Environment

  • Observed on latest main branch
  • Affects Fabric 3.x with inline_env=True (default)