diff options
| author | Emīls <emils@mullvad.net> | 2021-12-09 16:29:23 +0000 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2021-12-13 15:42:55 +0000 |
| commit | 2729ca03f9192a6ab60dd6ba041ff2d7ab3209f3 (patch) | |
| tree | a7f219bd02feb6464226771f5ad1e0a94e67e013 | |
| parent | 785254150f39e42256cf36fbf2d2901694dc6e7c (diff) | |
| download | mullvadvpn-2729ca03f9192a6ab60dd6ba041ff2d7ab3209f3.tar.xz mullvadvpn-2729ca03f9192a6ab60dd6ba041ff2d7ab3209f3.zip | |
Allow only root to reach the API in blocked state
| -rw-r--r-- | CHANGELOG.md | 5 | ||||
| -rw-r--r-- | docs/security.md | 9 | ||||
| -rw-r--r-- | talpid-core/src/firewall/linux.rs | 11 | ||||
| -rw-r--r-- | talpid-core/src/firewall/macos.rs | 10 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 2 |
5 files changed, 26 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e68fb7cdc..66500519a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,9 +67,10 @@ Line wrap the file at 100 chars. Th - Fix issue with the user getting kicked out of certain views in settings when the app is brought to the foreground. ### Security -#### Windows - Restrict which applications are allowed to communicate with the API while in a blocking state. - This prevents malicious scripts on websites from trying to do so. + This prevents malicious scripts on websites from trying to do so. On Windows, only + `mullvad-problem-report.exe` and `mullvad-daemon.exe` executables are allowed to reach the API, + whereas on Linux and macOS only root processes are able to reach the API. ## [2021.6] - 2021-11-17 diff --git a/docs/security.md b/docs/security.md index 8f1986642c..b7ddfea71e 100644 --- a/docs/security.md +++ b/docs/security.md @@ -101,10 +101,11 @@ forwarded. All other forward traffic is rejected. #### Mullvad API -The firewall allows traffic for the API regardless of tunnel state, to allow for updating keys, -fetching account data, etc. In the [Connected] state, this is only allowed inside the tunnel. -For the other states, it is allowed regardless. On Windows, only the Mullvad service and problem -report tool are able to communicate with the API in any of the blocking states. +The firewall allows traffic to the API regardless of tunnel state, so the daemon is able to update +keys, fetch account data, etc. In the [Connected] state, API traffic is only allowed inside the tunnel. +For the other states, API traffic will bypass the firewall. On Windows, only the Mullvad service and +problem report tool are able to communicate with the API in any of the blocking states. On macOS and +Linux all applications runnning as root are able to reach the API in blocking states. ### Disconnected diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs index c10aba6ba8..480bc3c674 100644 --- a/talpid-core/src/firewall/linux.rs +++ b/talpid-core/src/firewall/linux.rs @@ -653,15 +653,26 @@ impl<'a> PolicyBatch<'a> { self.batch.add(&out_rule, nftnl::MsgType::Add); } + /// Adds firewall rules allow traffic to flow to the API. Allows the app to reach the API in + /// blocked states. fn add_allow_endpoint_rules(&mut self, endpoint: &Endpoint) { let mut in_rule = Rule::new(&self.in_chain); check_endpoint(&mut in_rule, End::Src, endpoint); + let allowed_states = nftnl::expr::ct::States::ESTABLISHED.bits(); + in_rule.add_expr(&nft_expr!(ct state)); + in_rule.add_expr(&nft_expr!(bitwise mask allowed_states, xor 0u32)); + in_rule.add_expr(&nft_expr!(cmp != 0u32)); + in_rule.add_expr(&nft_expr!(meta skuid)); + in_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); + add_verdict(&mut in_rule, &Verdict::Accept); self.batch.add(&in_rule, nftnl::MsgType::Add); let mut out_rule = Rule::new(&self.out_chain); check_endpoint(&mut out_rule, End::Dst, endpoint); + out_rule.add_expr(&nft_expr!(meta skuid)); + out_rule.add_expr(&nft_expr!(cmp == super::ROOT_UID)); add_verdict(&mut out_rule, &Verdict::Accept); self.batch.add(&out_rule, nftnl::MsgType::Add); diff --git a/talpid-core/src/firewall/macos.rs b/talpid-core/src/firewall/macos.rs index a10f82bc69..de78524249 100644 --- a/talpid-core/src/firewall/macos.rs +++ b/talpid-core/src/firewall/macos.rs @@ -17,9 +17,6 @@ type Result<T> = std::result::Result<T, Error>; /// replaced by allowing the anchor name to be configured from the public API of this crate. const ANCHOR_NAME: &'static str = "mullvad"; -const ROOT_UID: u32 = 0; - -/// The macOS firewall and DNS implementation. pub struct Firewall { pf: pfctl::PfCtl, pf_was_enabled: Option<bool>, @@ -286,11 +283,13 @@ impl Firewall { .proto(pfctl_proto) .keep_state(pfctl::StatePolicy::Keep) .tcp_flags(Self::get_tcp_flags()) - .user(Uid::from(ROOT_UID)) + .user(Uid::from(super::ROOT_UID)) .quick(true) .build()?) } + /// Produces a rule that allows traffic to flow to the API. Allows the app to reach the API in + /// blocked states. fn get_allowed_endpoint_rule( &self, allowed_endpoint: net::Endpoint, @@ -303,6 +302,7 @@ impl Firewall { .to(allowed_endpoint.address) .proto(pfctl_proto) .keep_state(pfctl::StatePolicy::Keep) + .user(Uid::from(super::ROOT_UID)) .quick(true) .build()?) } @@ -359,7 +359,7 @@ impl Firewall { .direction(pfctl::Direction::Out) .to(*ip) .quick(true) - .user(Uid::from(ROOT_UID)) + .user(Uid::from(super::ROOT_UID)) .keep_state(pfctl::StatePolicy::Keep) .build()?, ); diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 80714d8338..761691e216 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -82,6 +82,8 @@ const DHCPV4_CLIENT_PORT: u16 = 68; const DHCPV6_SERVER_PORT: u16 = 547; #[cfg(all(unix, not(target_os = "android")))] const DHCPV6_CLIENT_PORT: u16 = 546; +#[cfg(all(unix, not(target_os = "android")))] +const ROOT_UID: u32 = 0; #[cfg(all(unix, not(target_os = "android")))] /// Returns whether an address belongs to a private subnet. |
