fix(install): skip and reject links when extracting .eti archives
Security audit findings EXP2-SEC-01, SEC-IPC-04 and Codex #3 (symlink redirection through externally extracted archives). The ordinary install path hands every root `.eti` archive to an external `unrar x` process and promotes the resulting staging directory to `local/` as soon as the extractor exits 0. Nothing inspected what unrar materialised. A symbolic link (or, on Windows, a junction) inside an archive would survive promotion and later redirect the launch-time settings rewrite in `apply_launch_settings_once`, the uninstall path, or any script the game ships. The archives themselves are BLAKE3 verified against the bundled catalog before they can be installed, so a hostile link would have to be published by the catalog operator; this is defense in depth rather than a live remote exploit. Two independent layers now guard promotion: - Both `unrar` invocations (Tauri sidecar and peer-cli external unpacker) pass `-ol-`, which makes unrar 7.x skip symbolic-link entries entirely. The bundled 7.10 sidecar was checked against a fixture archive. - `install_inner`/`update_inner` walk the staging tree without following links and refuse to promote it if any entry is a symlink or (on Windows) carries the reparse-point attribute. The normal rollback then removes staging and clears the install intent. The audit's `-sl-` suggestion does not exist in unrar; `-sl<size>` is a size filter. Post-extraction digest verification of every extracted file remains out of scope for the ordinary path; Stream Install already verifies each output entry. Test plan: `just test` (new unix test installs with a fake unpacker that plants a symlink and asserts install fails, `local/` is absent and the intent is cleared; the peer-cli controlled-unrar test checks the new argument position). Manual: install a fixture game via peer-cli. Claude-Session: https://claude.ai/code/session_017C3Nbgwpdm3YNwZhhFLHwg
This commit is contained in:
3 files changed
+99
-5
No files matched your search
@@ -3201,6 +3201,10 @@ async fn run_unrar_sidecar(
|
||||
[
|
||||
std::ffi::OsString::from("x"),
|
||||
std::ffi::OsString::from("-p-"),
|
||||
// Skip symbolic links inside the archive entirely. The install
|
||||
// transaction additionally refuses to promote a tree containing
|
||||
// links, so a link can never redirect later file operations.
|
||||
std::ffi::OsString::from("-ol-"),
|
||||
paths.archive.as_os_str().to_owned(),
|
||||
std::ffi::OsString::from("-y"),
|
||||
std::ffi::OsString::from("-o"),
|
||||
|
||||
Reference in new issue
Block a user