feat: add security headers

This commit is contained in:
neri 2023-04-20 21:46:56 +02:00
parent af59c099dd
commit b28d83a481
3 changed files with 22 additions and 6 deletions

2
Cargo.lock generated
View File

@ -436,7 +436,7 @@ dependencies = [
[[package]] [[package]]
name = "datatrash" name = "datatrash"
version = "2.3.1" version = "2.3.2"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-governor", "actix-governor",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "datatrash" name = "datatrash"
version = "2.3.1" version = "2.3.2"
authors = ["neri"] authors = ["neri"]
edition = "2021" edition = "2021"

View File

@ -12,7 +12,10 @@ use crate::rate_limit::ForwardedPeerIpKeyExtractor;
use actix_files::Files; use actix_files::Files;
use actix_governor::{Governor, GovernorConfigBuilder}; use actix_governor::{Governor, GovernorConfigBuilder};
use actix_web::{ 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}, middleware::{self, Condition, DefaultHeaders, Logger},
web::{self, Data}, web::{self, Data},
App, Error, HttpResponse, HttpServer, App, Error, HttpResponse, HttpServer,
@ -22,10 +25,19 @@ use sqlx::postgres::PgPool;
use std::env; use std::env;
use tokio::sync::mpsc::channel; use tokio::sync::mpsc::channel;
const DEFAULT_CSP: (HeaderName, &str) = ( const DEFAULT_CONTENT_SECURITY_POLICY: (HeaderName, &str) = (
CONTENT_SECURITY_POLICY, 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';" "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<HttpResponse, Error> { async fn not_found() -> Result<HttpResponse, Error> {
Ok(HttpResponse::NotFound() Ok(HttpResponse::NotFound()
@ -72,8 +84,12 @@ async fn main() -> std::io::Result<()> {
.wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#)) .wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#))
.wrap( .wrap(
DefaultHeaders::new() DefaultHeaders::new()
.add(DEFAULT_CSP) .add(DEFAULT_CONTENT_SECURITY_POLICY)
.add((X_CONTENT_TYPE_OPTIONS, HeaderValue::from_static("nosniff"))), .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::Compress::default())
.wrap(middleware::NormalizePath::trim()) .wrap(middleware::NormalizePath::trim())