Repository navigation
Releases
Releases · djunekz/miflasher
MiFlasher v2.0.4
Follow-up hardening release. Reported by Niranj R Mahaswar (@NiranjMahaswar).
Security
- Backup restore could write outside its extraction directory on older Python versions.
BackupManager._safe_extract()fell back to an unfilteredextractall()on Python 3.10.0-3.10.11 and 3.11.0-3.11.3, so a symlink inside a backup.tar.gzcould be used to write files outside the extraction directory. Archive validation now lives in the newcore/archive.pyand no longer depends on the interpreter: every member is checked for absolute paths, path traversal, special files (devices, FIFOs), and symlink or hardlink targets that resolve outside the destination. The tarfiledatafilter is applied on top of this when the interpreter provides it FlashManager._extract_tgz()uses the same validation. Previously it passedfilter="data"unconditionally, which raisedTypeErroron the affected Python versions, and it only checked member names, not link targets
Fixed
- Encrypted ZIPs and ZIPs using an unsupported compression method (
RuntimeError,NotImplementedError), as well as truncated archives (EOFError,zlib.error), no longer kill the flash thread. They are logged as errors and the flash is aborted - Backup restore now reports corrupt or unsafe archives (
TarError,EOFError,zlib.error,OSError) as errors instead of raising
Changed
- Bumped version strings to 2.0.4
MiFlasher v2.0.3
Security hardening release following the review of 2.0.2. Reported by
Niranj R Mahaswar (@NiranjMahaswar).
Security
- Archive extraction can no longer escape its temp directory. A ROM named
...tar.gzresolved its extraction directory toTEMP_DIR/.., and the cleanup step then deleted~/storage/downloads/MiFlasherincluding backups. Every extraction now uses a unique directory created withtempfile.mkdtemp()insideTEMP_DIR, so the archive file name no longer influences the path FlashManager._cleanup()now refuses to remove anything that does not resolve strictly insideTEMP_DIR/api/rebootnow requires"confirm": truelike the other state-changing endpoints, and the dashboard asks for confirmation before rebooting
Fixed
- Corrupt ZIP/TAR archives and unsafe TAR links (
BadZipFile,TarError,AbsoluteLinkError,OSError) no longer raise out of the flash path and kill the request thread; they are logged as errors and the flash is aborted. A partially extracted directory is removed when extraction fails gui_portwas saved from the GUI as a string and prevented the nextmiflasher guistart.ConfigManager.set()now converts integer settings toint, rejects non-numeric values and ports outside 1-65535, and/api/save-configreports invalid values.run_gui()also coerces an already-saved string port back to an integerConfigManager.set()no longer converts string settings such asthemeorslotto booleans- Payload flashing uses a unique extraction directory instead of the shared
payload_out
Documentation
SECURITY.mddocuments that a TLS reverse proxy must rewriteHostandOriginto the address the GUI is bound to, and that--host 0.0.0.0disables Host header validation (the token and Origin checks still apply)SECURITY.mdcredits the reporter
Changed
- Bumped version strings to 2.0.3
MiFlasher v2.0.2
Security release: fixes an unauthenticated remote code execution and arbitrary
device flashing issue in the Web GUI (CWE-306, CWE-352, CWE-94). Reported by
Niranj R Mahaswar (@NiranjMahaswar).
All users of 2.0.1 and earlier 2.x releases should upgrade.
Security
- Web GUI now requires an access token. A random token is generated at every
miflasher guistart and printed in the URL fragment (http://host:port/#token=...). Every/api/*request, GET and POST, must carry it in theX-MiFlasher-Tokenheader and is compared in constant time. Requests without a valid token get401 - CSRF and cross-origin access closed. The token travels in a custom header, so a browser cannot send it cross-origin without a CORS preflight, and the server never answers preflights.
Originmust matchHost, andPOSTbodies must beContent-Type: application/json(text/plainis rejected with415) - DNS rebinding protection. When bound to a loopback address the
Hostheader must belocalhost,127.0.0.1,[::1]or the configured host with the active port - Destructive GUI actions no longer auto-confirm.
CapturingLogger.confirm()used to always returnTrue./api/flash,/api/restore,/api/unlockand/api/wipenow require"confirm": truein the request body, sent only after the dashboard shows a confirmation dialog. Unlock and wipe no longer passforce=Trueand go through the normal confirmation path - ROM flash scripts are no longer executed blindly.
flash_all.sh/flash_all_lock.sh/flash_all_except_data_storage.shfrom a ROM archive now run only if one of these holds:--trust-script(CLI) or the "I trust this ROM" checkbox (GUI) is set, a--checksumwas supplied and verified, or the user approves after the script content is printed for review (CLI, interactive). In non-interactive contexts such as the GUI the script is refused otherwise. The script path is also checked to resolve inside the extraction directory - Strict request validation in the GUI API. Flash
target,slotandoptsare allow-listed; local sources must be an existing.zip,.tgz,.gz,.imgor.binfile; checksums must be hexadecimal; rebootmodeis allow-listed; partition names must match[A-Za-z0-9_-]{1,64}; request bodies are capped at 1 MiB and must be JSON objects - Partition names are also validated inside
BackupManager.backup()so a name like../../xcan no longer escape the backup directory from the CLI either /api/save-configonly accepts known configuration keys and can no longer changegui_host(network exposure can only be enabled from the command line or the config file)- Added
Content-Security-Policy,X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: no-referrer,Cross-Origin-Resource-Policy: same-originandCache-Control: no-storeto GUI responses miflasher gui --host 0.0.0.0(or any non-loopback host) now prints an explicit warning that anyone on the network holding the token can flash, wipe and unlock the connected device, and that traffic is plain HTTP
Added
--trust-scriptflag formiflasher flashto skip the script review prompt for ROMs you trust- Web GUI: SHA-256 checksum field and "I trust this ROM and allow its flash script to run" checkbox on the Flash page; confirmation dialogs for flash and restore, in addition to the existing ones for unlock and wipe
Logger.interactiveattribute so core code can tell a terminal session from the GUI
Changed
- Opening the dashboard now requires the full URL printed by
miflasher gui, including the#token=fragment. The token is moved intosessionStorageand removed from the address bar on load - Bumped version strings to 2.0.2
Verified
- Original proof of concept (
POST /api/flashwithOrigin: https://evil.exampleandContent-Type: text/plain, no token):403 Forbidden, no script executed - Same request without an
Originheader:401 Unauthorized - Valid token with
Origin: https://evil.example:403; valid token withtext/plain:415; forgedHost: evil.example:18080:403; wipe withoutconfirm:400;OPTIONSpreflight:501 - A ROM archive containing a malicious
flash_all.shwas refused with a valid token andconfirm: truebut notrust_script;$HOME/RCE_PROOFwas not created. Interactive CLI run without--trust-scriptprinted the script for review and aborted on a non-affirmative answer
MiFlasher v2.0.1
Patch release: fixes crashes, dead code, security holes, and non-functional
placeholders found in a full audit of v2.0.0.
Fixed
core/utils.pyandcore/payload.pywere broken (ImportError: cannot import name 'log' from 'core.logger') and are now removed — they were already unused dead code, andCHANGELOG.mdhad incorrectly claimed they were removed in 2.0.0miflasher wipecrashed with an unhandled traceback whenadb/fastbootwere not on PATH — now fails gracefully with a clear error message, consistent with every other commandcore/downloader.pycrashed at import time if therequestspackage was missing — now guarded, with a clear install hint shown only when a download is actually attempted_flash_payload()told users topip install payload-dumper-go, which doesn't exist as a pip package (it's a Go binary) — corrected to the real install instructions- Dead line of code in
flash.py(self.log.progress.__doc__) removed install.shno longer installs the unusedmiunlockpip package, and no longer patchesPATHwith a directory (~/.local/bin) that the launcher isn't actually installed into
Security
- Fixed a zip-slip / path-traversal vulnerability in ROM extraction (
flash.py) — a malicious ROM archive with../../paths in its entries could previously write files outside the extraction directory. Archive members are now validated before extraction. - Fixed the same path-traversal issue in
backup.py'srestore()when extracting.tar.gzbackups - Escaped device properties and log messages in the Web GUI dashboard before inserting them into
innerHTML, closing a reflected-XSS path via crafted devicegetpropvalues
Added
--checksumflag formiflasher flashso--skip-verifyhas something real to skip; checksum is verified for both local files and downloaded ROMs when provided--wipe-dataonmiflasher flashnow actually erasesuserdataafter a successful flash (previously accepted but silently ignored)--methodonmiflasher flash rom(script/fastboot/adb) is now respected instead of being ignoredmiflasher configvalues (slot,verbose,gui_host,gui_port) are now actually used as defaults by the CLI when the matching flag isn't passed explicitly — previouslyconfig --sethad no effect on program behavior- Web GUI:
/api/flash,/api/backup,/api/restore,/api/unlock, and/api/wipenow call the realcore.*managers instead of returning canned placeholder messages;/api/save-configactually persists settings;/api/configreturns the real saved config instead of hardcoded defaults; wiping dalvik-cache from the GUI now runs theadb rm -rfcommand instead of being silently skipped colorama.init()is now called so thecoloramadependency inrequirements.txtis actually used (fixes broken ANSI colors on older Windows terminals)- GUI server switched from single-threaded
HTTPServertoThreadingHTTPServerso device polling keeps working while a flash/backup/restore is in progress
MiFlasher v2.0.0
What's New
- flash target vbmeta, recovery, super
- progress bar rich, eta, size
- download resumable, retry, checksum
- gui interface
- logging
- error handling
Added
- reboot mode (system, bootloader, recovery, fastboot)
- backup (all partitions + compress)
- full restore from backup
- wipe (chache, data, dalvik)
Update
- cli and gui interface
- device stats info
- unlock verified with adb and official tool
MiFlasher v1.0.0
Release MiFlasher v1.0.0
Beta Release