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

Đang mở
#665 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
45/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
bash, python
Lĩnh vực
cli, security

Hướng nghiên cứu

Bắt đầu với fire/console/console_io.py và More(), sau đó kiểm tra fire/completion.py và _BashScript(), bao gồm cả bash_completion_template. Tái hiện cả hai PoC được cung cấp, gồm PoC pseudo-TTY và PoC sourced completion, sau đó thêm phạm vi kiểm thử hồi quy cho thấy PAGER và các tên do kẻ tấn công kiểm soát không thể thực thi lệnh shell; chạy bộ kiểm thử bị ảnh hưởng.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.
Ngôn ngữ chính
Python
Star
28.2k
Fork
1.5k
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của google/python-fire

Tất cả issue của google/python-fire

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.