From b28d83a481e40bfcc151971d0081a6d1192ccae0 Mon Sep 17 00:00:00 2001 From: neri Date: Thu, 20 Apr 2023 21:46:56 +0200 Subject: [PATCH] feat: add security headers --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 24 ++++++++++++++++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae3fef6..7334a6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,7 +436,7 @@ dependencies = [ [[package]] name = "datatrash" -version = "2.3.1" +version = "2.3.2" dependencies = [ "actix-files", "actix-governor", diff --git a/Cargo.toml b/Cargo.toml index 4da0fd5..6e92af7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "datatrash" -version = "2.3.1" +version = "2.3.2" authors = ["neri"] edition = "2021" diff --git a/src/main.rs b/src/main.rs index 345d783..605317d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,10 @@ use crate::rate_limit::ForwardedPeerIpKeyExtractor; use actix_files::Files; use actix_governor::{Governor, GovernorConfigBuilder}; use actix_web::{ - http::header::{HeaderName, HeaderValue, CONTENT_SECURITY_POLICY, X_CONTENT_TYPE_OPTIONS}, + http::header::{ + HeaderName, CONTENT_SECURITY_POLICY, PERMISSIONS_POLICY, REFERRER_POLICY, + X_CONTENT_TYPE_OPTIONS, X_FRAME_OPTIONS, X_XSS_PROTECTION, + }, middleware::{self, Condition, DefaultHeaders, Logger}, web::{self, Data}, App, Error, HttpResponse, HttpServer, @@ -22,10 +25,19 @@ use sqlx::postgres::PgPool; use std::env; use tokio::sync::mpsc::channel; -const DEFAULT_CSP: (HeaderName, &str) = ( +const DEFAULT_CONTENT_SECURITY_POLICY: (HeaderName, &str) = ( CONTENT_SECURITY_POLICY, "default-src 'none'; connect-src 'self'; img-src 'self'; media-src 'self'; font-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; base-uri 'self'; frame-src 'none'; frame-ancestors 'none'; form-action 'self';" ); +#[allow(clippy::declare_interior_mutable_const)] +const DEFAULT_PERMISSIONS: (HeaderName, &str) = ( + PERMISSIONS_POLICY, + "accelerometer=(), ambient-light-sensor=(), battery=(), camera=(), display-capture=(), document-domain=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=(), usb=(), web-share=()" +); +const DEFAULT_CONTENT_TYPE_OPTIONS: (HeaderName, &str) = (X_CONTENT_TYPE_OPTIONS, "nosniff"); +const DEFAULT_FRAME_OPTIONS: (HeaderName, &str) = (X_FRAME_OPTIONS, "deny"); +const DEFAULT_XSS_PROTECTION: (HeaderName, &str) = (X_XSS_PROTECTION, "1; mode=block"); +const DEFAULT_REFERRER_POLICY: (HeaderName, &str) = (REFERRER_POLICY, "no-referrer"); async fn not_found() -> Result { Ok(HttpResponse::NotFound() @@ -72,8 +84,12 @@ async fn main() -> std::io::Result<()> { .wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#)) .wrap( DefaultHeaders::new() - .add(DEFAULT_CSP) - .add((X_CONTENT_TYPE_OPTIONS, HeaderValue::from_static("nosniff"))), + .add(DEFAULT_CONTENT_SECURITY_POLICY) + .add(DEFAULT_PERMISSIONS) + .add(DEFAULT_CONTENT_TYPE_OPTIONS) + .add(DEFAULT_FRAME_OPTIONS) + .add(DEFAULT_XSS_PROTECTION) + .add(DEFAULT_REFERRER_POLICY), ) .wrap(middleware::Compress::default()) .wrap(middleware::NormalizePath::trim())