Steps to reproduce
- Prepare a local HTTP proxy that serves a crafted archive for Flutter's requested
windows-x64/artifacts.zip path while forwarding all other artifact requests upstream.
- Set
FLUTTER_STORAGE_BASE_URL to the local proxy.
- Remove any existing
bin\cache\artifacts\engine\windows-x64 and bin\cache\artifacts\engine\windows-x64-profile directories from the Flutter SDK cache.
- Serve a crafted archive containing the entry
../windows-x64-profile/poc_marker.txt for the requested windows-x64/artifacts.zip path.
- Run
flutter precache --windows -v.
- Inspect the engine cache directories after extraction.
Expected results
The archive extraction logic should reject any archive entry whose resolved destination escapes the intended extraction root.
A windows-x64 artifact archive should only be able to create files under:
bin\cache\artifacts\engine\windows-x64
and should not be able to write into sibling directories such as:
bin\cache\artifacts\engine\windows-x64-profile
Actual results
During normal flutter precache --windows -v execution, a crafted archive served for the requested windows-x64/artifacts.zip path was able to create:
bin\cache\artifacts\engine\windows-x64-profile\poc_marker.txt
even though the intended extraction root was:
bin\cache\artifacts\engine\windows-x64
This shows that _unpackArchive(...) allows an archive entry to escape the intended extraction root and write into a sibling engine cache directory.
Code sample
Code sample
// This issue is not triggered by application-level Dart code.
// It affects Flutter's Windows artifact extraction logic in:
//
// packages/flutter_tools/lib/src/base/os.dart
// _unpackArchive(...)
//
// The issue is reproduced by serving a crafted engine artifact archive
// for `windows-x64/artifacts.zip` during `flutter precache --windows`.
</details> ```
### Screenshots or Video
<details open>
<summary>Screenshots / Video demonstration</summary>
Attached:
- proxy request for `windows-x64/artifacts.zip`
- proxy response serving the crafted archive
- filesystem proof showing the intended extraction root and the escaped write path
- marker file contents and full path
- archive listing showing the traversal entry
</details>
<img width="964" height="52" alt="Image" src="https://github.com/user-attachments/assets/67aa0263-3a77-45ad-85e0-00084b37094b" />
<img width="1091" height="99" alt="Image" src="https://github.com/user-attachments/assets/fc86c178-7ebc-4001-bdec-715e08a1a8ff" />
<img width="945" height="251" alt="Image" src="https://github.com/user-attachments/assets/3f6a3b6f-ea47-40f2-8353-172c4bff1307" />
<img width="1031" height="116" alt="Image" src="https://github.com/user-attachments/assets/4002e34d-2e0c-40cf-84c0-13b04f6d8482" />
<img width="1089" height="146" alt="Image" src="https://github.com/user-attachments/assets/33b9a402-f456-4d90-acf8-c9f67a727250" />
### Logs
<details open><summary>Logs</summary>
```console
Command used:
flutter precache --windows -v
Relevant runtime evidence:
- Flutter requested: windows-x64/artifacts.zip
- The local proxy served the crafted archive for that exact path
- After extraction, the file bin\cache\artifacts\engine\windows-x64-profile\poc_marker.txt was created
- The intended extraction root was bin\cache\artifacts\engine\windows-x64
</details> ```
[engine_tree.txt](https://github.com/user-attachments/files/27218345/engine_tree.txt)
[windows-x64_artifacts.hash.txt](https://github.com/user-attachments/files/27218344/windows-x64_artifacts.hash.txt)
### Flutter Doctor output
<details open><summary>Doctor output</summary>
```console
[!] Flutter (Channel stable, 3.41.8, on Microsoft Windows [Version 10.0.26200.8246], locale en-US)
• Flutter version 3.41.8 on channel stable at C:\Users\x66\Downloads\flutter_windows_3.41.8-stable\flutter
! The flutter binary is not on your path. Consider adding
C:\Users\x66\Downloads\flutter_windows_3.41.8-stable\flutter\bin to your path.
! The dart binary is not on your path. Consider adding
C:\Users\x66\Downloads\flutter_windows_3.41.8-stable\flutter\bin to your path.
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 02085feb3f (5 days ago), 2026-04-24 13:54:45 -0700
• Engine revision 59aa584fdf
• Dart version 3.11.5
• DevTools version 2.54.2
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android,
enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file, enable-lldb-debugging,
enable-uiscene-migration
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly
to perform update checks and upgrades.
[√] Windows Version (11 Pro 64-bit, 25H2, 2009)
[X] Android toolchain - develop for Android devices
X Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/to/windows-android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[√] Chrome - develop for the web
• Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop Windows apps (Visual Studio Build Tools 2026 18.1.1)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools
• Visual Studio Build Tools 2026 version 18.1.11312.151
• Windows 10 SDK version 10.0.26100.0
[√] Connected device (3 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.26200.8246]
• Chrome (web) • chrome • web-javascript • Google Chrome 147.0.7727.103
• Edge (web) • edge • web-javascript • Microsoft Edge 147.0.3912.86
[√] Network resources
• All expected network resources are available.
! Doctor found issues in 2 categories.
</details> ```
Steps to reproduce
windows-x64/artifacts.zippath while forwarding all other artifact requests upstream.FLUTTER_STORAGE_BASE_URLto the local proxy.bin\cache\artifacts\engine\windows-x64andbin\cache\artifacts\engine\windows-x64-profiledirectories from the Flutter SDK cache.../windows-x64-profile/poc_marker.txtfor the requestedwindows-x64/artifacts.zippath.flutter precache --windows -v.Expected results
The archive extraction logic should reject any archive entry whose resolved destination escapes the intended extraction root.
A
windows-x64artifact archive should only be able to create files under:bin\cache\artifacts\engine\windows-x64and should not be able to write into sibling directories such as:
bin\cache\artifacts\engine\windows-x64-profileActual results
During normal
flutter precache --windows -vexecution, a crafted archive served for the requestedwindows-x64/artifacts.zippath was able to create:bin\cache\artifacts\engine\windows-x64-profile\poc_marker.txteven though the intended extraction root was:
bin\cache\artifacts\engine\windows-x64This shows that
_unpackArchive(...)allows an archive entry to escape the intended extraction root and write into a sibling engine cache directory.Code sample
Code sample