Merge pull request #44 from joseluisq/feature/security_headers_for_http_2
feat: security headers for http/2 by default
Diff
src/config.rs | 13 +++++++++++++
src/handler.rs | 8 +++++++-
src/lib.rs | 1 +
src/security_headers.rs | 35 +++++++++++++++++++++++++++++++++++
src/server.rs | 7 ++++++-
5 files changed, 62 insertions(+), 2 deletions(-)
@@ -108,4 +108,17 @@ pub struct Config {
)]
pub directory_listing: bool,
#[structopt(
long,
parse(try_from_str),
required_if("http2", "true"),
default_value_if("http2", Some("true"), "true"),
default_value = "false",
env = "SERVER_SECURITY_HEADERS"
)]
pub security_headers: bool,
}
@@ -2,7 +2,7 @@ use http::StatusCode;
use hyper::{Body, Request, Response};
use std::{future::Future, path::PathBuf, sync::Arc};
use crate::{compression, control_headers, cors, static_files};
use crate::{compression, control_headers, cors, security_headers, static_files};
use crate::{error_page, Error, Result};
@@ -11,6 +11,7 @@ pub struct RequestHandlerOpts {
pub compression: bool,
pub dir_listing: bool,
pub cors: Option<Arc<cors::Configured>>,
pub security_headers: bool,
}
@@ -50,6 +51,11 @@ impl RequestHandler {
.await
{
Ok(mut resp) => {
if self.opts.security_headers {
security_headers::with_security_headers(&mut resp);
}
if self.opts.compression {
resp = compression::auto(method, headers, resp)?;
@@ -11,6 +11,7 @@ pub mod error_page;
pub mod handler;
pub mod helpers;
pub mod logger;
pub mod security_headers;
pub mod server;
pub mod service;
pub mod signals;
@@ -0,0 +1,35 @@
use http::header::{
CONTENT_SECURITY_POLICY, STRICT_TRANSPORT_SECURITY, X_CONTENT_TYPE_OPTIONS, X_FRAME_OPTIONS,
X_XSS_PROTECTION,
};
use hyper::{Body, Response};
pub fn with_security_headers(resp: &mut Response<Body>) {
resp.headers_mut().insert(
STRICT_TRANSPORT_SECURITY,
"max-age=63072000; includeSubDomains; preload"
.parse()
.unwrap(),
);
resp.headers_mut()
.insert(X_FRAME_OPTIONS, "DENY".parse().unwrap());
resp.headers_mut()
.insert(X_XSS_PROTECTION, "1; mode=block".parse().unwrap());
resp.headers_mut()
.insert(X_CONTENT_TYPE_OPTIONS, "nosniff".parse().unwrap());
resp.headers_mut().insert(
CONTENT_SECURITY_POLICY,
"frame-ancestors 'self'".parse().unwrap(),
);
}
@@ -89,9 +89,13 @@ impl Server {
.set(helpers::read_file_content(opts.page50x.as_ref()))
.expect("page 50x is not initialized");
let security_headers = opts.security_headers;
tracing::info!("security headers: enabled={}", security_headers);
let compression = opts.compression;
tracing::info!("auto compression compression: enabled={}", compression);
tracing::info!("auto compression: enabled={}", compression);
let dir_listing = opts.directory_listing;
@@ -110,6 +114,7 @@ impl Server {
compression,
dir_listing,
cors,
security_headers,
},
});