DENY frames from other origins to prevent clickjacking

This commit is contained in:
Tomasz Drwięga 2016-05-31 21:39:11 +02:00
parent 3dd642abe9
commit 9957328607
2 changed files with 24 additions and 2 deletions

View File

@ -38,11 +38,13 @@ pub fn utils() -> Box<Endpoint> {
pub fn all_endpoints() -> Endpoints { pub fn all_endpoints() -> Endpoints {
let mut pages = Endpoints::new(); let mut pages = Endpoints::new();
pages.insert("proxy".to_owned(), ProxyPac::boxed()); pages.insert("proxy".into(), ProxyPac::boxed());
pages.insert("home".into(), Box::new(
PageEndpoint::new_safe_to_embed(parity_dapps_builtins::App::default())
));
insert::<parity_dapps_status::App>(&mut pages, "status"); insert::<parity_dapps_status::App>(&mut pages, "status");
insert::<parity_dapps_status::App>(&mut pages, "parity"); insert::<parity_dapps_status::App>(&mut pages, "parity");
insert::<parity_dapps_builtins::App>(&mut pages, "home");
wallet_page(&mut pages); wallet_page(&mut pages);
daodapp_page(&mut pages); daodapp_page(&mut pages);

View File

@ -30,6 +30,8 @@ pub struct PageEndpoint<T : WebApp + 'static> {
pub app: Arc<T>, pub app: Arc<T>,
/// Prefix to strip from the path (when `None` deducted from `app_id`) /// Prefix to strip from the path (when `None` deducted from `app_id`)
pub prefix: Option<String>, pub prefix: Option<String>,
/// Safe to be loaded in frame by other origin. (use wisely!)
safe_to_embed: bool,
} }
impl<T: WebApp + 'static> PageEndpoint<T> { impl<T: WebApp + 'static> PageEndpoint<T> {
@ -37,6 +39,7 @@ impl<T: WebApp + 'static> PageEndpoint<T> {
PageEndpoint { PageEndpoint {
app: Arc::new(app), app: Arc::new(app),
prefix: None, prefix: None,
safe_to_embed: false,
} }
} }
@ -44,6 +47,18 @@ impl<T: WebApp + 'static> PageEndpoint<T> {
PageEndpoint { PageEndpoint {
app: Arc::new(app), app: Arc::new(app),
prefix: Some(prefix), prefix: Some(prefix),
safe_to_embed: false,
}
}
/// Creates new `PageEndpoint` which can be safely used in iframe
/// even from different origin. It might be dangerous (clickjacking).
/// Use wisely!
pub fn new_safe_to_embed(app: T) -> Self {
PageEndpoint {
app: Arc::new(app),
prefix: None,
safe_to_embed: true,
} }
} }
} }
@ -61,6 +76,7 @@ impl<T: WebApp> Endpoint for PageEndpoint<T> {
path: path, path: path,
file: None, file: None,
write_pos: 0, write_pos: 0,
safe_to_embed: self.safe_to_embed,
}) })
} }
} }
@ -83,6 +99,7 @@ struct PageHandler<T: WebApp + 'static> {
path: EndpointPath, path: EndpointPath,
file: Option<String>, file: Option<String>,
write_pos: usize, write_pos: usize,
safe_to_embed: bool,
} }
impl<T: WebApp + 'static> PageHandler<T> { impl<T: WebApp + 'static> PageHandler<T> {
@ -128,6 +145,9 @@ impl<T: WebApp + 'static> server::Handler<HttpStream> for PageHandler<T> {
if let Some(f) = self.file.as_ref().and_then(|f| self.app.file(f)) { if let Some(f) = self.file.as_ref().and_then(|f| self.app.file(f)) {
res.set_status(StatusCode::Ok); res.set_status(StatusCode::Ok);
res.headers_mut().set(header::ContentType(f.content_type.parse().unwrap())); res.headers_mut().set(header::ContentType(f.content_type.parse().unwrap()));
if !self.safe_to_embed {
res.headers_mut().set_raw("X-Frame-Options", vec![b"SAMEORIGIN".to_vec()]);
}
Next::write() Next::write()
} else { } else {
res.set_status(StatusCode::NotFound); res.set_status(StatusCode::NotFound);