Python execute phase aborts with error_analysis when the package closes stdout (MCP stdio servers)

Aperta
#1,200 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 6 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
security

Direzione di ricerca

Start in sandboxes/dynamicanalysis/analyze-python.py, reading execute_package, execute_module, and do_execute to trace how output failures propagate. Reproduce with the rel-38 analysis image and mcp-server-time 2026.8.18. Done means a package that closes stdout no longer aborts execute with error_analysis, and later modules are still executed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

When a Python package closes sys.stdout during the execute phase — every MCP stdio server does, because the protocol owns stdout — analyze-python.py crashes on its own next print(). The phase ends with status error_analysis, and all modules after the current one are never executed.

The handler meant to survive a failing module prints as well, so the exception escapes it (sandboxes/dynamicanalysis/analyze-python.py on main, unchanged since #1153):

def execute_module(module):
    ...
    try:
        do_execute(module)
    except BaseException:
        print('Failed to execute code for module', module)   # raises again

Reproduction

Image gcr.io/ossf-malware-analysis/analysis (rel-38, sha256:1f3104f3f0cfddeaf62f0952d663e129cb5efe38486766e676fb926fa84c4c27), ecosystem pypi, package mcp-server-time 2026.8.18 (the reference MCP server from modelcontextprotocol/servers).

install and import complete. execute ends with "Status": "error_analysis", and its stderr is:

  File "/usr/local/bin/analyze-python.py", line 123, in execute_module
    do_execute(module)
  File "/usr/local/bin/analyze-python.py", line 170, in do_execute
    print('[skipped members]', ' '.join(skipped_names))
ValueError: I/O operation on closed file.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/analyze-python.py", line 338, in <module>
    exit(main())
  File "/usr/local/bin/analyze-python.py", line 332, in main
    phase(package)
  File "/usr/local/bin/analyze-python.py", line 112, in execute_package
    execute_module(module)
  File "/usr/local/bin/analyze-python.py", line 126, in execute_module
    print('Failed to execute code for module', module)
ValueError: I/O operation on closed file.

Expected

The harness keeps its own output channel independent of the package under analysis (for example, it writes to a duplicate of fd 1 taken at start-up, or restores sys.stdout / falls back to sys.__stderr__ when a write fails), so a package that closes stdout is analysed completely instead of aborting the execute phase.

Why it matters

Consumers that treat error_analysis as an incomplete result get no verdict for most MCP stdio servers. A malicious package could also close stdout on purpose to stop the execute phase before later modules run.

Lingua principale
Go
Stelle
925
Fork
75
Merge medio
4g 2h
PR unite (30g)
3

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di ossf/package-analysis

Tutte le issue di ossf/package-analysis

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.