mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-07-19 08:47:19 +00:00
fix(LCEL-01): disable arbitrary-path IPC + remove opener ** scope
three changes: 1. file_dialogs::write_binary_file / read_binary_file used to accept arbitrary paths with no validation, no dialog, no scope. now they refuse all paths. callers must use pick_file / save_file_dialog. 2. plugins::list_directory used to accept arbitrary paths with no validation. now it refuses all paths. callers must use get_plugins_dir. 3. capabilities/default.json had opener:allow-open-path scoped to path: "**" which let the webview launch ANY local path. removed that entry entirely. opener:allow-reveal-item-in-dir is left for now (used by the file manager UI). combined, these close the webview -> arbitrary write+execute primitive. the proper fix is to scope opener:allow-open-path to a specific games directory once we know what paths the launcher actually needs to open.
This commit is contained in:
parent
8da6a217bc
commit
8c941a6b72
|
|
@ -23,14 +23,13 @@
|
|||
"gamepad:default",
|
||||
"drpc:default",
|
||||
"updater:default",
|
||||
{
|
||||
"identifier": "opener:allow-open-path",
|
||||
"allow": [
|
||||
{
|
||||
"path": "**"
|
||||
}
|
||||
]
|
||||
},
|
||||
// security: removed opener:allow-open-path with path: "**" - that
|
||||
// scoped the webview to launch ANY local path. combined with
|
||||
// write_binary_file + list_directory (now disabled, see file_dialogs.rs
|
||||
// and plugins.rs) a compromised webview had a full RCE primitive.
|
||||
// (LCEL-01)
|
||||
// TODO: scope to a specific games directory (e.g. the instance dir)
|
||||
// once we know what paths the launcher actually needs to open.
|
||||
{
|
||||
"identifier": "opener:allow-reveal-item-in-dir",
|
||||
"allow": [
|
||||
|
|
|
|||
|
|
@ -40,12 +40,20 @@ pub fn save_file_dialog(title: String, filename: String, filters: Vec<String>) -
|
|||
}
|
||||
}
|
||||
|
||||
// security: write_binary_file / read_binary_file used to accept arbitrary
|
||||
// paths with no validation, no dialog, no scope. combined with the
|
||||
// opener:allow-open-path: ** capability, a compromised webview could
|
||||
// write+launch any file anywhere. (LCEL-01)
|
||||
// TODO: scope these to a launcher-specific subdirectory with canonical
|
||||
// containment checks, or remove from the IPC surface entirely and route
|
||||
// all binary file ops through rfd-gated dialogs.
|
||||
// for now, refuse all paths. callers must use pick_file / save_file_dialog.
|
||||
#[tauri::command]
|
||||
pub fn write_binary_file(path: String, data: Vec<u8>) -> Result<(), String> {
|
||||
fs::write(path, data).map_err(|e| e.to_string())
|
||||
pub fn write_binary_file(_path: String, _data: Vec<u8>) -> Result<(), String> {
|
||||
Err("write_binary_file disabled: use save_file_dialog instead".into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn read_binary_file(path: String) -> Result<Vec<u8>, String> {
|
||||
fs::read(path).map_err(|e| e.to_string())
|
||||
pub fn read_binary_file(_path: String) -> Result<Vec<u8>, String> {
|
||||
Err("read_binary_file disabled: use pick_file instead".into())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,16 +15,13 @@ pub fn get_plugins_dir(app: tauri::AppHandle) -> Result<String, String> {
|
|||
|
||||
#[tauri::command]
|
||||
pub fn list_directory(path: String) -> Result<Vec<DirEntry>, String> {
|
||||
let entries = fs::read_dir(&path).map_err(|e| e.to_string())?;
|
||||
let mut results = Vec::new();
|
||||
for entry in entries {
|
||||
let entry = entry.map_err(|e| e.to_string())?;
|
||||
results.push(DirEntry {
|
||||
name: entry.file_name().to_string_lossy().to_string(),
|
||||
is_dir: entry.file_type().map(|t| t.is_dir()).unwrap_or(false),
|
||||
});
|
||||
}
|
||||
Ok(results)
|
||||
// security: list_directory used to accept arbitrary paths with no
|
||||
// validation. combined with write_binary_file + opener:allow-open-path: **
|
||||
// a compromised webview could enumerate startup folders, drop a binary,
|
||||
// and launch it. (LCEL-01)
|
||||
// TODO: scope to the launcher's plugins dir or remove from IPC entirely.
|
||||
// for now, refuse all paths.
|
||||
Err("list_directory disabled: use get_plugins_dir instead".into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
|
|
|||
Loading…
Reference in a new issue