Add Content-Security-Policy and X-Content-Type-Options headers to all responses

This commit is contained in:
silverpill 2023-02-22 15:18:19 +00:00
parent 6fa4ed96c8
commit 227eef2d6b
5 changed files with 30 additions and 8 deletions

View file

@ -15,13 +15,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Added `/api/v1/statuses/{status_id}/thread` API endpoint (replaces `/api/v1/statuses/{status_id}/context`). - Added `/api/v1/statuses/{status_id}/thread` API endpoint (replaces `/api/v1/statuses/{status_id}/context`).
- Accept webfinger requests where `resource` is instance actor ID. - Accept webfinger requests where `resource` is instance actor ID.
- Added `proxy_set_header X-Forwarded-Proto $scheme;` directive to nginx config example. - Added `proxy_set_header X-Forwarded-Proto $scheme;` directive to nginx config example.
- Add `Content-Security-Policy` and `X-Content-Type-Options` headers to all responses.
### Changed ### Changed
- Allow `instance_uri` configuration value to contain URI scheme. - Allow `instance_uri` configuration value to contain URI scheme.
- Changed `Content-Security-Policy` header value in nginx config examples.
- Changed `/api/v1/statuses/{status_id}/context` response format to match Mastodon API. - Changed `/api/v1/statuses/{status_id}/context` response format to match Mastodon API.
- Changed status code of `/api/v1/statuses` response to 200 to match Mastodon API. - Changed status code of `/api/v1/statuses` response to 200 to match Mastodon API.
- Removed `add_header` directives for `Content-Security-Policy` and `X-Content-Type-Options` headers from nginx config example.
### Deprecated ### Deprecated

View file

@ -31,8 +31,8 @@ server {
ssl_stapling_verify on; ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always; add_header Strict-Transport-Security "max-age=63072000" always;
# script-src unsafe-inline required by MetaMask
# style-src oauth-authorization required by OAuth authorization page # CSP header can't be added in location block
add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; img-src 'self' data:; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'nonce-oauth-authorization'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"; add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; img-src 'self' data:; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'nonce-oauth-authorization'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'";
add_header X-Content-Type-Options "nosniff"; add_header X-Content-Type-Options "nosniff";

View file

@ -31,10 +31,6 @@ server {
ssl_stapling_verify on; ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always; add_header Strict-Transport-Security "max-age=63072000" always;
# script-src unsafe-inline required by MetaMask
# style-src oauth-authorization required by OAuth authorization page
add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; img-src 'self' data:; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'nonce-oauth-authorization'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'";
add_header X-Content-Type-Options "nosniff";
client_max_body_size 10M; client_max_body_size 10M;

View file

@ -3,7 +3,11 @@ use actix_web::{
dev::{ConnectionInfo, ServiceResponse}, dev::{ConnectionInfo, ServiceResponse},
error::{Error, JsonPayloadError}, error::{Error, JsonPayloadError},
http::StatusCode, http::StatusCode,
middleware::{ErrorHandlerResponse, ErrorHandlers}, middleware::{
DefaultHeaders,
ErrorHandlerResponse,
ErrorHandlers,
},
web::{Form, Json}, web::{Form, Json},
Either, Either,
HttpRequest, HttpRequest,
@ -36,6 +40,25 @@ pub fn create_auth_error_handler<B: MessageBody + 'static>() -> ErrorHandlers<B>
}) })
} }
pub fn create_default_headers_middleware() -> DefaultHeaders {
DefaultHeaders::new()
.add((
"Content-Security-Policy",
// script-src unsafe-inline required by MetaMask
// style-src oauth-authorization required by OAuth authorization page
"default-src 'none'; \
connect-src 'self'; \
img-src 'self' data:; \
media-src 'self'; \
script-src 'self' 'unsafe-inline'; \
style-src 'self' 'nonce-oauth-authorization'; \
frame-ancestors 'none'; \
base-uri 'self'; \
form-action 'self'",
))
.add(("X-Content-Type-Options", "nosniff"))
}
/// Convert JSON payload deserialization errors into validation errors /// Convert JSON payload deserialization errors into validation errors
pub fn json_error_handler( pub fn json_error_handler(
error: JsonPayloadError, error: JsonPayloadError,

View file

@ -17,6 +17,7 @@ use mitra::database::migrate::apply_migrations;
use mitra::ethereum::contracts::get_contracts; use mitra::ethereum::contracts::get_contracts;
use mitra::http::{ use mitra::http::{
create_auth_error_handler, create_auth_error_handler,
create_default_headers_middleware,
json_error_handler, json_error_handler,
}; };
use mitra::job_queue::scheduler; use mitra::job_queue::scheduler;
@ -133,6 +134,7 @@ async fn main() -> std::io::Result<()> {
} }
}) })
.wrap(create_auth_error_handler()) .wrap(create_auth_error_handler())
.wrap(create_default_headers_middleware())
.app_data(web::PayloadConfig::default().limit(UPLOAD_MAX_SIZE * 2)) .app_data(web::PayloadConfig::default().limit(UPLOAD_MAX_SIZE * 2))
.app_data(web::JsonConfig::default() .app_data(web::JsonConfig::default()
.limit(UPLOAD_MAX_SIZE * 2) .limit(UPLOAD_MAX_SIZE * 2)