fix(backend): Serve valid headers for HSTS and HSTS preload
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
parent
b1aac6acc3
commit
238fb2727d
|
@ -174,6 +174,12 @@ id: 'aidx'
|
|||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Whether to enable HSTS preload
|
||||
# Read these before enabling:
|
||||
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security
|
||||
# - https://hstspreload.org/
|
||||
#hstsPreload: false
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
|
|
|
@ -168,6 +168,12 @@ id: 'aidx'
|
|||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Whether to enable HSTS preload
|
||||
# Read these before enabling:
|
||||
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security
|
||||
# - https://hstspreload.org/
|
||||
#hstsPreload: false
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
|
|
|
@ -250,6 +250,12 @@ id: 'aidx'
|
|||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Whether to enable HSTS preload
|
||||
# Read these before enabling:
|
||||
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security
|
||||
# - https://hstspreload.org/
|
||||
#hstsPreload: false
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
|
|
|
@ -161,6 +161,12 @@ id: 'aidx'
|
|||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Whether to enable HSTS preload
|
||||
# Read these before enabling:
|
||||
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security
|
||||
# - https://hstspreload.org/
|
||||
#hstsPreload: false
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
|
|
|
@ -182,6 +182,12 @@ id: "aidx"
|
|||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Whether to enable HSTS preload
|
||||
# Read these before enabling:
|
||||
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#preloading_strict_transport_security
|
||||
# - https://hstspreload.org/
|
||||
#hstsPreload: false
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ type Source = {
|
|||
socket?: string;
|
||||
chmodSocket?: string;
|
||||
disableHsts?: boolean;
|
||||
hstsPreload?: boolean;
|
||||
db: {
|
||||
host: string;
|
||||
port: number;
|
||||
|
@ -107,6 +108,7 @@ export type Config = {
|
|||
socket: string | undefined;
|
||||
chmodSocket: string | undefined;
|
||||
disableHsts: boolean | undefined;
|
||||
hstsPreload: boolean | undefined;
|
||||
db: {
|
||||
host: string;
|
||||
port: number;
|
||||
|
@ -241,6 +243,7 @@ export function loadConfig(): Config {
|
|||
socket: config.socket,
|
||||
chmodSocket: config.chmodSocket,
|
||||
disableHsts: config.disableHsts,
|
||||
hstsPreload: config.hstsPreload ?? false,
|
||||
host,
|
||||
hostname,
|
||||
scheme,
|
||||
|
|
|
@ -31,6 +31,7 @@ import { HealthServerService } from './HealthServerService.js';
|
|||
import { ClientServerService } from './web/ClientServerService.js';
|
||||
import { OpenApiServerService } from './api/openapi/OpenApiServerService.js';
|
||||
import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js';
|
||||
import { makeHstsHook } from './hsts.js';
|
||||
|
||||
const _dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
|
@ -81,12 +82,10 @@ export class ServerService implements OnApplicationShutdown {
|
|||
this.#fastify = fastify;
|
||||
|
||||
// HSTS
|
||||
// 6months (15552000sec)
|
||||
if (this.config.url.startsWith('https') && !this.config.disableHsts) {
|
||||
fastify.addHook('onRequest', (request, reply, done) => {
|
||||
reply.header('strict-transport-security', 'max-age=15552000; preload');
|
||||
done();
|
||||
});
|
||||
const preload = this.config.hstsPreload;
|
||||
const host = new URL(this.config.url).host;
|
||||
fastify.addHook('onRequest', makeHstsHook(host, preload));
|
||||
}
|
||||
|
||||
// Register raw-body parser for ActivityPub HTTP signature validation.
|
||||
|
|
30
packages/backend/src/server/hsts.ts
Normal file
30
packages/backend/src/server/hsts.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import type { onRequestHookHandler } from "fastify";
|
||||
|
||||
// 6months (15552000sec) by default, 1year (31536000sec) if preload is enabled
|
||||
export function makeHstsHook(host: string, preload: boolean = false): onRequestHookHandler {
|
||||
if (preload) {
|
||||
return (request, reply, done) => {
|
||||
// we must permanent redirect http to https for preload to be eligible
|
||||
// however we do not want to do this if a reverse proxy is detected
|
||||
if (
|
||||
(request.host === host || request.hostname === host) &&
|
||||
(request.headers['x-forwarded-proto'] ?? request.protocol) === 'http') {
|
||||
reply.redirect(`https://${request.hostname}${request.url}`, 301);
|
||||
} else {
|
||||
// 1 year is mandatory for preload
|
||||
reply.header('strict-transport-security', 'max-age=31536000; includeSubDomains; preload');
|
||||
}
|
||||
done();
|
||||
}
|
||||
} else {
|
||||
return (request, reply, done) => {
|
||||
reply.header('strict-transport-security', 'max-age=15552000');
|
||||
done();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@ import { FeedService } from './FeedService.js';
|
|||
import { UrlPreviewService } from './UrlPreviewService.js';
|
||||
import { ClientLoggerService } from './ClientLoggerService.js';
|
||||
import type { FastifyInstance, FastifyPluginOptions, FastifyReply } from 'fastify';
|
||||
import { makeHstsHook } from '../hsts.js';
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
const _dirname = dirname(_filename);
|
||||
|
@ -207,6 +208,13 @@ export class ClientServerService {
|
|||
//#region Bull Dashboard
|
||||
const bullBoardPath = '/queue';
|
||||
|
||||
// HSTS
|
||||
if (this.config.url.startsWith('https') && !this.config.disableHsts) {
|
||||
const preload = this.config.hstsPreload;
|
||||
const host = new URL(this.config.url).host;
|
||||
fastify.addHook('onRequest', makeHstsHook(host, preload));
|
||||
}
|
||||
|
||||
// Authenticate
|
||||
fastify.addHook('onRequest', async (request, reply) => {
|
||||
if (request.routeOptions.url == null) {
|
||||
|
|
Loading…
Reference in a new issue