fix(fs): do not deserialize customFlags from IPC (#3634)

In plugins/fs/src/lib.rs OpenOptions, custom_flags was deserializable
from the `open` command arguments even though it is not in the TS types,
so a webview with a read-only permission set could pass arbitrary open(2)
flags such as O_TRUNC.

The field is now #[serde(skip)]; Rust callers still set it through
OpenOptionsExt. Rejecting write/truncate/create options of `open` under
read-only sets changes permission semantics and is deferred to v3.
This commit is contained in:
Lucas Fernandes Nogueira authored and GitHub committed 2026-10-09 13:05:12 -03:00
1 parent 77d00a4f54
commit 5de7ebfc95
2 files changed
+17 -1

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
---
fs: patch
fs-js: patch
---
**Security:** the `open` command no longer accepts a `customFlags` option from the webview. It was not part of the JavaScript types and let the webview pass arbitrary `open(2)` flags (e.g. `O_TRUNC`) to files it may only read. `OpenOptionsExt::custom_flags` still works from Rust.
+11 -1
View File
@@ -83,7 +83,9 @@ pub struct OpenOptions {
#[serde(default)]
#[allow(unused)]
mode: Option<u32>,
#[serde(default)]
// Never deserialized: the webview must not be able to pass arbitrary `open(2)` flags
// (e.g. `O_TRUNC`), it can only be set from Rust with `OpenOptionsExt::custom_flags`.
#[serde(skip)]
#[allow(unused)]
custom_flags: Option<i32>,
}
@@ -663,4 +665,12 @@ mod tests {
"w"
);
}
#[test]
fn open_options_ignore_custom_flags_from_ipc() {
let options: OpenOptions =
serde_json::from_str(r#"{ "read": true, "customFlags": 512 }"#).unwrap();
assert!(options.read);
assert_eq!(options.custom_flags, None);
}
}