mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-31 05:41:13 +00:00 
			
		
		
		
	Merge pull request #643 from BlackDex/icon-security
Updated icon blacklisting.
This commit is contained in:
		
				commit
				
					
						99a635d327
					
				
			
		
					 3 changed files with 45 additions and 11 deletions
				
			
		|  | @ -1,12 +1,13 @@ | |||
| use std::fs::{create_dir_all, remove_file, symlink_metadata, File}; | ||||
| use std::io::prelude::*; | ||||
| use std::net::ToSocketAddrs; | ||||
| use std::time::{Duration, SystemTime}; | ||||
| 
 | ||||
| use rocket::http::ContentType; | ||||
| use rocket::response::Content; | ||||
| use rocket::Route; | ||||
| 
 | ||||
| use reqwest::{header::HeaderMap, Client, Response}; | ||||
| use reqwest::{header::HeaderMap, Client, Response, Url}; | ||||
| 
 | ||||
| use rocket::http::Cookie; | ||||
| 
 | ||||
|  | @ -60,15 +61,9 @@ fn icon(domain: String) -> Content<Vec<u8>> { | |||
|         return Content(icon_type, FALLBACK_ICON.to_vec()); | ||||
|     } | ||||
| 
 | ||||
|     if let Some(blacklist) = CONFIG.icon_blacklist_regex() { | ||||
|         info!("Icon blacklist enabled: {:#?}", blacklist); | ||||
| 
 | ||||
|         let regex = Regex::new(&blacklist).expect("Valid Regex"); | ||||
| 
 | ||||
|         if regex.is_match(&domain) { | ||||
|             warn!("Blacklisted domain: {:#?}", domain); | ||||
|             return Content(icon_type, FALLBACK_ICON.to_vec()); | ||||
|         } | ||||
|     if check_icon_domain_is_blacklisted(&domain) { | ||||
|         warn!("Domain is blacklisted: {:#?}", domain); | ||||
|         return Content(icon_type, FALLBACK_ICON.to_vec()); | ||||
|     } | ||||
| 
 | ||||
|     let icon = get_icon(&domain); | ||||
|  | @ -76,6 +71,37 @@ fn icon(domain: String) -> Content<Vec<u8>> { | |||
|     Content(icon_type, icon) | ||||
| } | ||||
| 
 | ||||
| fn check_icon_domain_is_blacklisted(domain: &str) -> bool { | ||||
|     let mut is_blacklisted = false; | ||||
|     if CONFIG.icon_blacklist_non_global_ips() { | ||||
|         is_blacklisted = (domain, 0) | ||||
|             .to_socket_addrs() | ||||
|             .map(|x| { | ||||
|                 for ip_port in x { | ||||
|                     if !ip_port.ip().is_global() { | ||||
|                         warn!("IP {} for domain '{}' is not a global IP!", ip_port.ip(), domain); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                 false | ||||
|             }) | ||||
|             .unwrap_or(false); | ||||
|     } | ||||
| 
 | ||||
|     // Skip the regex check if the previous one is true already
 | ||||
|     if !is_blacklisted { | ||||
|         if let Some(blacklist) = CONFIG.icon_blacklist_regex() { | ||||
|             let regex = Regex::new(&blacklist).expect("Valid Regex"); | ||||
|             if regex.is_match(&domain) { | ||||
|                 warn!("Blacklisted domain: {:#?} matched {:#?}", domain, blacklist); | ||||
|                 is_blacklisted = true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     is_blacklisted | ||||
| } | ||||
| 
 | ||||
| fn get_icon(domain: &str) -> Vec<u8> { | ||||
|     let path = format!("{}/{}.png", CONFIG.icon_cache_folder(), domain); | ||||
| 
 | ||||
|  | @ -202,6 +228,7 @@ fn get_icon_url(domain: &str) -> Result<(Vec<Icon>, String), Error> { | |||
|     if let Ok(content) = resp { | ||||
|         // Extract the URL from the respose in case redirects occured (like @ gitlab.com)
 | ||||
|         let url = content.url().clone(); | ||||
| 
 | ||||
|         let raw_cookies = content.headers().get_all("set-cookie"); | ||||
|         cookie_str = raw_cookies | ||||
|             .iter() | ||||
|  | @ -253,6 +280,10 @@ fn get_page(url: &str) -> Result<Response, Error> { | |||
| } | ||||
| 
 | ||||
| fn get_page_with_cookies(url: &str, cookie_str: &str) -> Result<Response, Error> { | ||||
|     if check_icon_domain_is_blacklisted(Url::parse(url).unwrap().host_str().unwrap_or_default()) { | ||||
|         err!("Favicon rel linked to a non blacklisted domain!"); | ||||
|     } | ||||
| 
 | ||||
|     if cookie_str.is_empty() { | ||||
|         CLIENT | ||||
|             .get(url) | ||||
|  |  | |||
|  | @ -267,6 +267,9 @@ make_config! { | |||
|         /// Icon blacklist Regex |> Any domains or IPs that match this regex won't be fetched by the icon service.
 | ||||
|         /// Useful to hide other servers in the local network. Check the WIKI for more details
 | ||||
|         icon_blacklist_regex:   String, true,   option; | ||||
|         /// Icon blacklist non global IPs |> Any IP which is not defined as a global IP will be blacklisted.
 | ||||
|         /// Usefull to secure your internal environment: See https://en.wikipedia.org/wiki/Reserved_IP_addresses for a list of IPs which it will block
 | ||||
|         icon_blacklist_non_global_ips:  bool,   true,   def,    true; | ||||
| 
 | ||||
|         /// Disable Two-Factor remember |> Enabling this would force the users to use a second factor to login every time.
 | ||||
|         /// Note that the checkbox would still be present, but ignored.
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| #![feature(proc_macro_hygiene, decl_macro, vec_remove_item, try_trait)] | ||||
| #![feature(proc_macro_hygiene, decl_macro, vec_remove_item, try_trait, ip)] | ||||
| #![recursion_limit = "256"] | ||||
| 
 | ||||
| #[cfg(feature = "openssl")] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue