Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

python-fire: (1) PAGER+shell=True RCE in console_io.More (2) bash $(...) runs when sourcing --completion from maliciously named .py file. PoC verified.

オープン
#665 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
bash, python
領域
cli, security

調査の方向性

fire/console/console_io.py と More() から始め、次に fire/completion.py と _BashScript() を調査し、bash_completion_template も確認します。提供されている pseudo-TTY と sourced completion の両方の PoC を再現し、その後、攻撃者が制御する PAGER と名前によって shell コマンドを実行できないことを示す回帰テストを追加し、影響を受けるテストスイートを実行します。

索引モデルが issue の本文から書いたものです。

説明

Summary

Two related issues in python-fire (library + python -m fire entrypoint): (1) OS command injection when an external pager is spawned; (2) arbitrary shell command execution when a user sources a generated Bash completion script, if the CLI name (often derived from a .py filename) contains Bash command substitution or other shell metacharacters.

Repository: https://github.com/google/python-fire


Issue A: PAGER + subprocess.Popen(..., shell=True)

File: fire/console/console_io.py, function More(), approximately lines 81–100.

Behavior: When check_pager is true (default), stdin/stdout are TTYs, and PAGER is set, the value from os.environ['PAGER'] is passed to:

subprocess.Popen(pager, stdin=subprocess.PIPE, shell=True)

Because shell=True, the string is interpreted by /bin/sh. Metacharacters (;, |, `, $(), etc.) allow arbitrary commands to run in the same security context as the Fire-based process.

Trigger: Any code path that calls console_io.More() with the default pager behavior—e.g. fire.core.Display() used for help text, traces, and other paged output—when the process has a malicious or attacker-controlled PAGER and an interactive terminal.

Verification (PoC): With PAGER='touch /tmp/fire_verify_pager', run under a pseudo-TTY (e.g. script -qefc 'python -c "from fire.console import console_io; import sys; console_io.More(\"x\", sys.stdout)"' /dev/null). The side-effect file appears, confirming shell interpretation of PAGER.


Issue B: Bash completion script — unsanitized name / identifier

File: fire/completion.py, function _BashScript(), template bash_completion_template and .format(...) around lines 179–187.

Behavior: The Bash script embeds name and identifier with only a weak transform:

identifier = name.replace('/', '').replace('.', '').replace(',', '')

Characters such as $, (, ), `, ;, newlines, etc. are not removed. The template includes lines such as:

  • _complete-{identifier}()
  • complete -F _complete-{identifier} {command}

with command=name. When the generated script is sourced by Bash, command substitution in identifier or name (e.g. $(touch marker)) is evaluated.

Trigger: python -m fire sets name from os.path.basename(path) (fire/__main__.py, import_from_file_path). A file named like $(touch _marker).py therefore yields a completion script that runs touch (or worse) when the victim runs source on the output of -- --completion.

Verification (PoC): Create a minimal module file literally named $(touch _fire_verify_completion_marker).py, run python -m fire '<path>' -- --completion > comp.sh, then bash -c 'source comp.sh'. The marker file is created (Bash may also error on an invalid function name, but substitution still runs).

Note: A subshell payload must not contain / in the basename (invalid filename on Unix); use e.g. $(touch _marker) with a relative target.


CWE mapping

  • Issue A: CWE-78 (OS command injection)
  • Issue B: CWE-78 / insufficient neutralization of shell metacharacters in generated shell code

Who can exploit

  • Issue A: Anyone who can control the environment of a process that runs Fire and reaches More() on a TTY with PAGER set (e.g. misconfigured services, wrappers, CI jobs, compromised .env, multi-tenant job runners). The user running the CLI can also set PAGER themselves; the higher risk is untrusted or inherited environment for automated or privileged contexts.
  • Issue B: An attacker who can place or name a .py file on disk (or otherwise influence the name passed to fire.Fire(..., name=...)) and convince a victim to generate and source Bash completion from that module (e.g. cloned repo, malicious path, social engineering). Supply-chain / “run this install script” scenarios are plausible.

What the attacker gains

  • Issue A: Arbitrary code execution as the Fire process user: read/write secrets the process can access, lateral movement on the host, data destruction (CIA triad: High).
  • Issue B: Arbitrary code execution as the user who sources the completion script in Bash—typically the developer’s or operator’s interactive account.

Prerequisites / limits

  • Issue A requires an interactive TTY for the default pager path (IsInteractive(output=True)); non-TTY falls back to writing without PAGER.
  • Issue B requires the victim to execute the generated script in Bash (e.g. source); reading the file alone is not enough.

Suggested severity (informal)

  • Issue A: often assessed High locally (e.g. CVSS ~8.x) when env is attacker-influenced; lower if only self-controlled env.
  • Issue B: High when sourcing untrusted completion is realistic; depends on social/engineering and workflow.
主要言語
Python
スター
28.2k
フォーク
1.5k
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

google/python-fire のほかの issue

google/python-fire の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。