refactor(http)!: always enforce the scope on redirects (#3600)

* refactor(http)!: always enforce the scope on redirects

Removes the `scopeRedirects` option (and the `Config` struct with it) that
was added as an opt-in in 2.7.0. Every hop of a redirect chain is now
checked against the URL scope, so a server on an allowed origin can no
longer redirect the request to a URL the scope denies.

`tauri_plugin_http::init()` returns `TauriPlugin<R>` again.

* chore(http): compile without warnings when the cookies feature is disabled
This commit is contained in:
Lucas Fernandes Nogueira
2026-09-22 06:03:27 -03:00
committed by GitHub
parent b566f09124
commit 34a06e7f60
5 changed files with 37 additions and 116 deletions
+11 -20
View File
@@ -44,20 +44,12 @@
//! - **unsafe-headers**: Allows webview requests to send any headers.
//! - **dangerous-settings**: Allows dangerous client settings such as accepting invalid certificates or hostnames.
//!
//! ## Configuration
//! ## Security
//!
//! See [`Config`] for the options that can be set on the `plugins > http` object of your
//! `tauri.conf.json`:
//!
//! ```json
//! {
//! "plugins": {
//! "http": {
//! "scopeRedirects": true
//! }
//! }
//! }
//! ```
//! The URL scope is checked on every hop of a redirect chain, not only on the URL requested by
//! the frontend, so every redirect target must also be allowed by the scope. Otherwise a server on
//! an allowed origin could redirect the request to any other origin - a `localhost` service, an
//! internal host or a cloud metadata endpoint - and hand its response to the webview.
pub use reqwest;
use tauri::{
@@ -65,11 +57,9 @@ use tauri::{
Manager, Runtime,
};
pub use config::Config;
pub use error::{Error, Result};
mod commands;
mod config;
mod error;
#[cfg(feature = "cookies")]
mod reqwest_cookie_store;
@@ -79,14 +69,13 @@ mod scope;
const COOKIES_FILENAME: &str = ".cookies";
pub(crate) struct Http {
pub(crate) config: Config,
#[cfg(feature = "cookies")]
cookies_jar: std::sync::Arc<crate::reqwest_cookie_store::CookieStoreMutex>,
}
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
Builder::<R, Option<Config>>::new("http")
.setup(|app, api| {
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("http")
.setup(|app, _api| {
#[cfg(feature = "cookies")]
let cookies_jar = {
use crate::reqwest_cookie_store::*;
@@ -114,7 +103,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
};
let state = Http {
config: api.config().clone().unwrap_or_default(),
#[cfg(feature = "cookies")]
cookies_jar: std::sync::Arc::new(cookies_jar),
};
@@ -138,6 +126,9 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<Config>> {
}
}
}
#[cfg(not(feature = "cookies"))]
let _ = (app, event);
})
.invoke_handler(tauri::generate_handler![
commands::fetch,