|
|
@ -1,7 +1,7 @@ |
|
|
|
//
|
|
|
|
// Web Headers and caching
|
|
|
|
//
|
|
|
|
use std::io::Cursor; |
|
|
|
use std::io::{Cursor, ErrorKind}; |
|
|
|
|
|
|
|
use rocket::{ |
|
|
|
fairing::{Fairing, Info, Kind}, |
|
|
@ -60,19 +60,34 @@ impl Fairing for AppHeaders { |
|
|
|
// Leaked Passwords check: api.pwnedpasswords.com
|
|
|
|
// 2FA/MFA Site check: 2fa.directory
|
|
|
|
// # Mail Relay: https://bitwarden.com/blog/add-privacy-and-security-using-email-aliases-with-bitwarden/
|
|
|
|
// app.simplelogin.io, app.anonaddy.com, api.fastmail.com
|
|
|
|
// app.simplelogin.io, app.anonaddy.com, api.fastmail.com, quack.duckduckgo.com
|
|
|
|
let csp = format!( |
|
|
|
"default-src 'self'; \ |
|
|
|
object-src 'self' blob:; \ |
|
|
|
script-src 'self'{script_src}; \ |
|
|
|
style-src 'self' 'unsafe-inline'; \ |
|
|
|
img-src 'self' data: https://haveibeenpwned.com/ https://www.gravatar.com {icon_service_csp}; \
|
|
|
|
child-src 'self' https://*.duosecurity.com https://*.duofederal.com; \
|
|
|
|
frame-src 'self' https://*.duosecurity.com https://*.duofederal.com; \
|
|
|
|
connect-src 'self' https://api.pwnedpasswords.com/range/ https://2fa.directory/api/ https://app.simplelogin.io/api/ https://app.anonaddy.com/api/ https://api.fastmail.com/; \
|
|
|
|
object-src 'self' blob:; \ |
|
|
|
frame-ancestors 'self' chrome-extension://nngceckbapebfimnlniiiahkandclblb chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh moz-extension://* {allowed_iframe_ancestors};",
|
|
|
|
icon_service_csp=CONFIG._icon_service_csp(), |
|
|
|
allowed_iframe_ancestors=CONFIG.allowed_iframe_ancestors() |
|
|
|
frame-ancestors 'self' \ |
|
|
|
chrome-extension://nngceckbapebfimnlniiiahkandclblb \
|
|
|
|
chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh \
|
|
|
|
moz-extension://* \
|
|
|
|
{allowed_iframe_ancestors}; \ |
|
|
|
img-src 'self' data: \ |
|
|
|
https://haveibeenpwned.com/ \
|
|
|
|
https://www.gravatar.com \
|
|
|
|
{icon_service_csp}; \ |
|
|
|
connect-src 'self' \ |
|
|
|
https://api.pwnedpasswords.com/range/ \
|
|
|
|
https://2fa.directory/api/ \
|
|
|
|
https://app.simplelogin.io/api/ \
|
|
|
|
https://app.anonaddy.com/api/ \
|
|
|
|
https://api.fastmail.com/ \
|
|
|
|
https://quack.duckduckgo.com/api/email/ \
|
|
|
|
;\ |
|
|
|
", |
|
|
|
icon_service_csp = CONFIG._icon_service_csp(), |
|
|
|
allowed_iframe_ancestors = CONFIG.allowed_iframe_ancestors() |
|
|
|
); |
|
|
|
res.set_raw_header("Content-Security-Policy", csp); |
|
|
|
res.set_raw_header("X-Frame-Options", "SAMEORIGIN"); |
|
|
@ -311,7 +326,16 @@ pub fn file_exists(path: &str) -> bool { |
|
|
|
|
|
|
|
pub fn write_file(path: &str, content: &[u8]) -> Result<(), crate::error::Error> { |
|
|
|
use std::io::Write; |
|
|
|
let mut f = File::create(path)?; |
|
|
|
let mut f = match File::create(path) { |
|
|
|
Ok(file) => file, |
|
|
|
Err(e) => { |
|
|
|
if e.kind() == ErrorKind::PermissionDenied { |
|
|
|
error!("Can't create '{}': Permission denied", path); |
|
|
|
} |
|
|
|
return Err(From::from(e)); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
f.write_all(content)?; |
|
|
|
f.flush()?; |
|
|
|
Ok(()) |
|
|
|