tauri_plugin_http/config.rs
1// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5use serde::Deserialize;
6
7/// HTTP plugin configuration, defined on the `plugins > http` object of your `tauri.conf.json`.
8#[derive(Debug, Clone, Default, Deserialize)]
9#[serde(rename_all = "camelCase", deny_unknown_fields)]
10pub struct Config {
11 /// Whether the scope is checked on every hop of a redirect chain instead of only on the
12 /// URL requested by the frontend. Defaults to `false`.
13 ///
14 /// When disabled, a server on an allowed origin can answer with a redirect to any other
15 /// origin - an open redirect, or a server an attacker controls - and the plugin follows it,
16 /// handing the webview a response from a URL the scope denies, such as a `localhost`
17 /// service, an internal host or a cloud metadata endpoint.
18 ///
19 /// When enabled, a redirect to a URL that is not allowed by the scope fails with
20 /// [`Error::UrlNotAllowed`](crate::Error::UrlNotAllowed) instead of being followed, so every
21 /// redirect target must also be part of the scope. This is opt-in because it breaks
22 /// applications that rely on being redirected outside of their configured scope.
23 // TODO(v3): enforce the scope on redirects by default and remove this option
24 #[serde(default)]
25 pub scope_redirects: bool,
26}
27
28#[cfg(test)]
29mod tests {
30 use super::Config;
31
32 #[test]
33 fn deserializes_the_plugin_configuration() {
34 // the plugin configuration is optional, and the scope check is opt-in
35 let config: Option<Config> = serde_json::from_value(serde_json::Value::Null).unwrap();
36 assert!(config.is_none());
37
38 let config: Config = serde_json::from_str("{}").unwrap();
39 assert!(!config.scope_redirects);
40
41 let config: Config = serde_json::from_str(r#"{ "scopeRedirects": true }"#).unwrap();
42 assert!(config.scope_redirects);
43
44 // a typo must not silently disable the scope check
45 assert!(serde_json::from_str::<Config>(r#"{ "scopeRedirect": true }"#).is_err());
46 }
47}