Skip to content

Commit

Permalink
Merge pull request from GHSA-57fm-592m-34r7
Browse files Browse the repository at this point in the history
* add __TAURI_INVOKE_KEY__ to ipc calls to detect initialized frames

* move ipc key check to start of on_message

* cargo +nightly fmt

* undo Cargo.toml formatting changes

* undo Cargo.toml formatting changes

* undo Cargo.toml formatting changes

* remove merged changefiles

* undo formatting changes to js files

* undo formatting changes to js files

* Update to patched wry  release

* fix: optional chaining is not supported on older webviews (#9529)

* Revert "undo formatting changes to js files"

This reverts commit a7ef0d91ea1b183e091ea65a2b201d65522cc1d5.

* Revert "undo formatting changes to js files"

This reverts commit 0fcfd4664b915af51b71e7ea68929fd5b6cb5fc3.

* revert core.js

* inject __TAURI_INVOKE_KEY__ to __TAURI_IPC__ instead

* remove unrelated changes file

* remove left over dbg! call

* change file

---------

Co-authored-by: Tillmann <28728469+tweidinger@users.noreply.github.com>
Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
  • Loading branch information
3 people committed May 22, 2024
1 parent 50aabad commit f6d81df
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 96 deletions.
6 changes: 6 additions & 0 deletions .changes/ipc-only-main-frame.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": patch:sec
"tauri-runtime-wry": patch:sec
---

Only process IPC commands from the main frame.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exclude = [ "CHANGELOG.md", "/target" ]
readme = "README.md"

[dependencies]
wry = { version = "0.24.6", default-features = false, features = [ "file-drop", "protocol" ] }
wry = { version = "0.24.10", default-features = false, features = [ "file-drop", "protocol" ] }
tauri-runtime = { version = "0.14.3", path = "../tauri-runtime" }
tauri-utils = { version = "1.5.4", path = "../tauri-utils" }
uuid = { version = "1", features = [ "v4" ] }
Expand Down
1 change: 1 addition & 0 deletions core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ encoding_rs = "0.8.31"
sys-locale = { version = "0.2.3", optional = true }
tracing = { version = "0.1", optional = true }
indexmap = { version = "1", features = [ "std", "serde" ], optional = true }
getrandom = { version = "0.2", features = [ "std" ] }

[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
rfd = { version = "0.10", optional = true, features = [ "gtk3", "common-controls-v6" ] }
Expand Down
22 changes: 8 additions & 14 deletions core/tauri/scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,25 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

; (function () {
;(function() {
__RAW_freeze_prototype__

; (function () {
__RAW_hotkeys__
})()
;(function() {
__RAW_hotkeys__
})()

__RAW_pattern_script__

__RAW_ipc_script__
; (function () {
__RAW_bundle_script__
})()
;(function() {
__RAW_bundle_script__
})()

__RAW_listen_function__

__RAW_core_script__

__RAW_event_initialization_script__

if (window.ipc) {
window.__TAURI_INVOKE__('__initialized', { url: window.location.href })
} else {
window.addEventListener('DOMContentLoaded', function () {
window.__TAURI_INVOKE__('__initialized', { url: window.location.href })
})
}
window.__TAURI_INVOKE__('__initialized', { url: window.location.href })
})()
12 changes: 11 additions & 1 deletion core/tauri/scripts/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

;
(function () {
(function() {
/**
* @type {string}
*/
Expand All @@ -18,6 +18,15 @@
*/
const isolationOrigin = __TEMPLATE_isolation_origin__

/**
* A runtime generated key to ensure an IPC call comes from an initialized frame.
*
* This is declared outside the `window.__TAURI_INVOKE__` definition to prevent
* the key from being leaked by `window.__TAURI_INVOKE__.toString()`.
* @var {string} __TEMPLATE_invoke_key__
*/
const __TAURI_INVOKE_KEY__ = __TEMPLATE_invoke_key__

/**
* @type {{queue: object[], ready: boolean, frame: HTMLElement | null}}
*/
Expand Down Expand Up @@ -85,6 +94,7 @@
Object.defineProperty(window, '__TAURI_IPC__', {
// todo: JSDoc this function
value: Object.freeze((message) => {
message.__TAURI_INVOKE_KEY__ = __TAURI_INVOKE_KEY__
switch (pattern) {
case 'brownfield':
window.__TAURI_POST_MESSAGE__(message)
Expand Down
1 change: 1 addition & 0 deletions core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1569,6 +1569,7 @@ impl<R: Runtime> Builder<R> {
self.window_event_listeners,
(self.menu, self.menu_event_listeners),
(self.invoke_responder, self.invoke_initialization_script),
crate::generate_invoke_key()?,
);

let http_scheme = manager.config().tauri.security.dangerous_use_http_scheme;
Expand Down
6 changes: 6 additions & 0 deletions core/tauri/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ pub enum Error {
/// The Window's raw handle is invalid for the platform.
#[error("Unexpected `raw_window_handle` for the current platform")]
InvalidWindowHandle,
/// Something went wrong with the CSPRNG.
#[error("unable to generate random bytes from the operating system: {0}")]
Csprng(#[from] getrandom::Error),
/// Bad `__TAURI_INVOKE_KEY__` value received in ipc message.
#[error("bad __TAURI_INVOKE_KEY__ value received in ipc message")]
InvokeKey,
}

pub(crate) fn into_anyhow<T: std::fmt::Display>(err: T) -> anyhow::Error {
Expand Down
5 changes: 5 additions & 0 deletions core/tauri/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub type OnPageLoad<R> = dyn Fn(Window<R>, PageLoadPayload) + Send + Sync + 'sta
#[default_template("../scripts/ipc.js")]
pub(crate) struct IpcJavascript<'a> {
pub(crate) isolation_origin: &'a str,
pub(crate) invoke_key: &'a str,
}

#[cfg(feature = "isolation")]
Expand Down Expand Up @@ -66,6 +67,10 @@ pub struct InvokePayload {
#[serde(rename = "__tauriModule")]
#[doc(hidden)]
pub tauri_module: Option<String>,
/// A secret key that only Tauri initialized frames have.
#[serde(rename = "__TAURI_INVOKE_KEY__")]
#[doc(hidden)]
pub invoke_key: Option<String>,
/// The success callback.
pub callback: CallbackFn,
/// The error callback.
Expand Down
49 changes: 49 additions & 0 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,3 +1091,52 @@ mod test_utils {
}
}
}

/// Simple dependency-free string encoder using [Z85].
mod z85 {
const TABLE: &[u8; 85] =
b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#";

/// Encode bytes with [Z85].
///
/// # Panics
///
/// Will panic if the input bytes are not a multiple of 4.
pub fn encode(bytes: &[u8]) -> String {
assert_eq!(bytes.len() % 4, 0);

let mut buf = String::with_capacity(bytes.len() * 5 / 4);
for chunk in bytes.chunks_exact(4) {
let mut chars = [0u8; 5];
let mut chunk = u32::from_be_bytes(chunk.try_into().unwrap()) as usize;
for byte in chars.iter_mut().rev() {
*byte = TABLE[chunk % 85];
chunk /= 85;
}

buf.push_str(std::str::from_utf8(&chars).unwrap());
}

buf
}

#[cfg(test)]
mod tests {
#[test]
fn encode() {
assert_eq!(
super::encode(&[0x86, 0x4F, 0xD2, 0x6F, 0xB5, 0x59, 0xF7, 0x5B]),
"HelloWorld"
);
}
}
}

/// Generate a random 128-bit [Z85] encoded [`String`].
///
/// [Z85]: https://rfc.zeromq.org/spec/32/
pub(crate) fn generate_invoke_key() -> Result<String> {
let mut bytes = [0u8; 16];
getrandom::getrandom(&mut bytes)?;
Ok(z85::encode(&bytes))
}
11 changes: 11 additions & 0 deletions core/tauri/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ pub struct InnerWindowManager<R: Runtime> {
invoke_initialization_script: String,
/// Application pattern.
pub(crate) pattern: Pattern,
/// A runtime generated key to ensure an IPC call comes from an initialized frame.
invoke_key: String,
}

impl<R: Runtime> fmt::Debug for InnerWindowManager<R> {
Expand All @@ -252,6 +254,7 @@ impl<R: Runtime> fmt::Debug for InnerWindowManager<R> {
.field("package_info", &self.package_info)
.field("menu", &self.menu)
.field("pattern", &self.pattern)
.field("invoke_key", &self.invoke_key)
.finish()
}
}
Expand Down Expand Up @@ -303,6 +306,7 @@ impl<R: Runtime> WindowManager<R> {
window_event_listeners: Vec<GlobalWindowEventListener<R>>,
(menu, menu_event_listeners): (Option<Menu>, Vec<GlobalMenuEventListener<R>>),
(invoke_responder, invoke_initialization_script): (Arc<InvokeResponder<R>>, String),
invoke_key: String,
) -> Self {
// generate a random isolation key at runtime
#[cfg(feature = "isolation")]
Expand Down Expand Up @@ -333,6 +337,7 @@ impl<R: Runtime> WindowManager<R> {
window_event_listeners: Arc::new(window_event_listeners),
invoke_responder,
invoke_initialization_script,
invoke_key,
}),
}
}
Expand Down Expand Up @@ -449,6 +454,7 @@ impl<R: Runtime> WindowManager<R> {
}
_ => "".to_string(),
},
invoke_key: self.invoke_key(),
}
.render_default(&Default::default())?;

Expand Down Expand Up @@ -896,6 +902,10 @@ impl<R: Runtime> WindowManager<R> {
listeners = self.event_listeners_object_name()
)
}

pub(crate) fn invoke_key(&self) -> &str {
&self.inner.invoke_key
}
}

#[cfg(test)]
Expand All @@ -917,6 +927,7 @@ mod test {
Default::default(),
Default::default(),
(std::sync::Arc::new(|_, _, _, _| ()), "".into()),
crate::generate_invoke_key().unwrap(),
);

#[cfg(custom_protocol)]
Expand Down
Loading

0 comments on commit f6d81df

Please sign in to comment.