Описание
Flyto2 Core: Arbitrary file write via image.download (and other file-writing modules)
Summary
image.download fetches a URL and writes the response to disk. It does not use the central path guard (validate_path_with_env_config, which confines writes to FLYTO_SANDBOX_DIR); instead it confines the output to output_dir, but output_dir is itself a caller parameter. Since the attacker sets both the target and the base it is checked against, the check is meaningless, and attacker-controlled bytes (the HTTP response) land at any absolute path the process can write.
Affected code
src/core/modules/atomic/image/download.py:
commonpath is used correctly, but the base is caller-supplied, so setting output_dir='/' passes any target. file.write, by contrast, uses validate_path_with_env_config() and stays inside FLYTO_SANDBOX_DIR.
This is not isolated to image.download. Most other file-writing modules write to a caller output_path with no path check at all: image.convert, image.resize, image.crop, image.compress, image.rotate, image.watermark, image.qrcode_generate, document.excel_write, document.pdf_fill_form, document.word_to_pdf, document.pdf_to_word and browser.pagination. Their content is format-constrained (a valid PNG/XLSX/SVG/PDF) but the path is fully attacker-chosen; image.download is the strongest because the bytes are arbitrary.
Reproduction
Save as filewrite_poc.py, run with PYTHONPATH=src/src python filewrite_poc.py. It sets FLYTO_SANDBOX_DIR to a sandbox dir and writes to a sibling directory outside it.
Output:
file.write refuses the out-of-sandbox path; image.download writes attacker bytes there. Reproduced through the running HTTP API as well.
Reachability (why this is not operator self-service)
output_dir, output_path and url are not supplied by the trusted operator. Every non-denylisted module is exposed to an AI agent through the generic execute_module(module_id, params) MCP tool (core/mcp_handler.py, params taken from the model's arguments) and to hosted-API clients, so these parameters are chosen by the LLM (which processes untrusted content) or a remote client. FLYTO_SANDBOX_DIR and the guard file.write uses exist specifically to confine file operations to a directory the caller cannot change; this module ignores that confinement and lets the caller pick both the target and the base it is checked against. Defeating a confinement control the vendor built is a bug, not intended behavior.
Impact
Write arbitrary content to an arbitrary path outside the operator's sandbox — overwrite config, drop a shell profile, cron job or authorized_keys, or replace a Python module, leading to code execution in typical deployments. The URL is SSRF-checked, so the attacker hosts the payload on their own public server (which the guard allows).
Suggested fix
Use validate_path_with_env_config() for every module that writes files, so all writes are confined to FLYTO_SANDBOX_DIR (a base the caller cannot change), never to a caller-supplied output_dir.
Пакеты
flyto-core
< 2.26.7
2.26.7
Связанные уязвимости
Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.6, image.download and related file-writing modules use caller-controlled output_dir instead of validate_path_with_env_config and its FLYTO_SANDBOX_DIR confinement, allowing attacker-controlled response bytes to be written to arbitrary filesystem paths the process can access. This issue is fixed in version 2.26.6.