From daf19f24b6f7d5c86833288fa95a6dc21c39473a Mon Sep 17 00:00:00 2001 From: amrbashir Date: Thu, 30 May 2024 20:50:28 +0300 Subject: [PATCH 1/5] feat(http): allow setting `origin` for unsafe headers closes #1389 --- .changes/http-origin-unsafe.md | 6 ++++ plugins/http/src/commands.rs | 63 +++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 .changes/http-origin-unsafe.md diff --git a/.changes/http-origin-unsafe.md b/.changes/http-origin-unsafe.md new file mode 100644 index 0000000000..dce1cd1f82 --- /dev/null +++ b/.changes/http-origin-unsafe.md @@ -0,0 +1,6 @@ +--- +"http": "patch" +"http-js": "patch" +--- + +Allow setting `Oigin` header when `unsafe-headers` feature flag is active. diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index 4f89f1fe61..c99b1ea8ad 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -201,29 +201,7 @@ pub async fn fetch( for (name, value) in &headers { let name = HeaderName::from_bytes(name.as_bytes())?; #[cfg(not(feature = "unsafe-headers"))] - if matches!( - name, - // forbidden headers per fetch spec https://fetch.spec.whatwg.org/#terminology-headers - header::ACCEPT_CHARSET - | header::ACCEPT_ENCODING - | header::ACCESS_CONTROL_REQUEST_HEADERS - | header::ACCESS_CONTROL_REQUEST_METHOD - | header::CONNECTION - | header::CONTENT_LENGTH - | header::COOKIE - | header::DATE - | header::DNT - | header::EXPECT - | header::HOST - | header::ORIGIN - | header::REFERER - | header::SET_COOKIE - | header::TE - | header::TRAILER - | header::TRANSFER_ENCODING - | header::UPGRADE - | header::VIA - ) { + if is_unsafe_header(&name) { continue; } @@ -246,7 +224,14 @@ pub async fn fetch( request = request.header(header::USER_AGENT, "tauri-plugin-http"); } - request = request.header(header::ORIGIN, webview.url()?.as_str()); + let unsafe_headers = cfg!(feature = "unsafe-header"); + if !unsafe_headers + || unsafe_headers && !headers.contains_key(header::ORIGIN.as_str()) + { + if let Ok(url) = webview.url() { + request = request.header(header::ORIGIN, url.as_str()); + } + } if let Some(data) = data { request = request.body(data); @@ -343,3 +328,33 @@ pub(crate) async fn fetch_read_body( let res = Arc::into_inner(res).unwrap().0; Ok(tauri::ipc::Response::new(res.bytes().await?.to_vec())) } + +// forbidden headers per fetch spec https://fetch.spec.whatwg.org/#terminology-headers +#[cfg(not(feature = "unsafe-headers"))] +fn is_unsafe_header(header: &HeaderName) -> bool { + matches!( + *header, + header::ACCEPT_CHARSET + | header::ACCEPT_ENCODING + | header::ACCESS_CONTROL_REQUEST_HEADERS + | header::ACCESS_CONTROL_REQUEST_METHOD + | header::CONNECTION + | header::CONTENT_LENGTH + | header::COOKIE + | header::DATE + | header::DNT + | header::EXPECT + | header::HOST + | header::ORIGIN + | header::REFERER + | header::SET_COOKIE + | header::TE + | header::TRAILER + | header::TRANSFER_ENCODING + | header::UPGRADE + | header::VIA + ) || { + let lower = header.as_str().to_lowercase(); + lower.starts_with("proxy-") || lower.starts_with("sec-") + } +} From 6a5e6a085fa007c6c80a7e877680eebe9771f11b Mon Sep 17 00:00:00 2001 From: amrbashir Date: Thu, 30 May 2024 20:57:12 +0300 Subject: [PATCH 2/5] clippy --- plugins/http/src/commands.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index c99b1ea8ad..07c5d87a71 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -224,9 +224,8 @@ pub async fn fetch( request = request.header(header::USER_AGENT, "tauri-plugin-http"); } - let unsafe_headers = cfg!(feature = "unsafe-header"); - if !unsafe_headers - || unsafe_headers && !headers.contains_key(header::ORIGIN.as_str()) + if !(cfg!(feature = "unsafe-header") + && headers.contains_key(header::ORIGIN.as_str())) { if let Ok(url) = webview.url() { request = request.header(header::ORIGIN, url.as_str()); From d3d3f80248fd2cf4f765104de2e93516d9f32ffa Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Thu, 30 May 2024 21:05:56 +0300 Subject: [PATCH 3/5] Update .changes/http-origin-unsafe.md Co-authored-by: Lucas Fernandes Nogueira --- .changes/http-origin-unsafe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/http-origin-unsafe.md b/.changes/http-origin-unsafe.md index dce1cd1f82..b2b4fef6c2 100644 --- a/.changes/http-origin-unsafe.md +++ b/.changes/http-origin-unsafe.md @@ -3,4 +3,4 @@ "http-js": "patch" --- -Allow setting `Oigin` header when `unsafe-headers` feature flag is active. +Allow setting `Origin` header when `unsafe-headers` feature flag is active. From 633a2e9e9cbd0f6393f6134b3f07ffcfb6952ebc Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Thu, 30 May 2024 21:06:42 +0300 Subject: [PATCH 4/5] Update commands.rs --- plugins/http/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index 07c5d87a71..dd86cd2e9f 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -224,7 +224,7 @@ pub async fn fetch( request = request.header(header::USER_AGENT, "tauri-plugin-http"); } - if !(cfg!(feature = "unsafe-header") + if !(cfg!(feature = "unsafe-headers") && headers.contains_key(header::ORIGIN.as_str())) { if let Ok(url) = webview.url() { From 9a55862825026bb731a686d3f638eef6c1cda09f Mon Sep 17 00:00:00 2001 From: amrbashir Date: Thu, 30 May 2024 21:12:47 +0300 Subject: [PATCH 5/5] set origin not full url --- plugins/http/src/commands.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index dd86cd2e9f..5c895ebc16 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -228,7 +228,8 @@ pub async fn fetch( && headers.contains_key(header::ORIGIN.as_str())) { if let Ok(url) = webview.url() { - request = request.header(header::ORIGIN, url.as_str()); + request = + request.header(header::ORIGIN, url.origin().ascii_serialization()); } }