feat: define secure static hosting contract

This commit is contained in:
2026-09-02 09:44:15 +03:00
parent 672ba80d9b
commit 847e6e4da9
8 changed files with 638 additions and 27 deletions

View File

@@ -5,6 +5,7 @@ import type {
SiteConfig,
} from './types.ts';
import { serializeJsonLd } from '../security/serialize-json-ld.ts';
import { createSecurityHeaders } from '../security/security-policy.ts';
interface PersonJsonLd {
'@type': 'Person';
@@ -108,28 +109,19 @@ export const createPageMetadata = (
};
};
const contentSecurityPolicy = (jsonLdCspHash: string): string => [
"default-src 'self'",
`script-src 'self' '${jsonLdCspHash}'`,
"style-src 'self'",
"img-src 'self'",
"media-src 'self'",
"font-src 'self'",
"connect-src 'none'",
"object-src 'none'",
"base-uri 'none'",
"frame-ancestors 'none'",
"form-action 'none'",
'upgrade-insecure-requests',
].join('; ');
const commonHeaders = (metadata: Readonly<PageMetadata>): string[] => [
` Content-Security-Policy: ${contentSecurityPolicy(metadata.jsonLdCspHash)}`,
' X-Content-Type-Options: nosniff',
' Referrer-Policy: no-referrer',
' Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()',
' X-Frame-Options: DENY',
];
const commonHeaders = (
metadata: Readonly<PageMetadata>,
site: Readonly<SiteConfig>,
): string[] => {
const headers = createSecurityHeaders(site, metadata.jsonLdCspHash);
return [
` Content-Security-Policy: ${headers.csp}`,
` X-Content-Type-Options: ${headers.contentTypeOptions}`,
` Referrer-Policy: ${headers.referrerPolicy}`,
` Permissions-Policy: ${headers.permissionsPolicy}`,
` X-Frame-Options: ${headers.frameOptions}`,
];
};
export const createStaticHostArtifacts = (
metadata: Readonly<PageMetadata>,
@@ -140,7 +132,7 @@ export const createStaticHostArtifacts = (
robots: 'User-agent: *\nDisallow: /\n',
headers: [
'/*',
...commonHeaders(metadata),
...commonHeaders(metadata, site),
' Cache-Control: private, no-store',
' X-Robots-Tag: noindex, nofollow, noarchive',
'',
@@ -164,7 +156,7 @@ export const createStaticHostArtifacts = (
' Cache-Control: public, max-age=31536000, immutable',
'',
'/*',
...commonHeaders(metadata),
...commonHeaders(metadata, site),
' Cache-Control: public, max-age=0, must-revalidate',
' Strict-Transport-Security: max-age=31536000',
'',