feat: define secure static hosting contract
This commit is contained in:
@@ -311,15 +311,18 @@ const assertMetadata = (html, inputs) => {
|
||||
|
||||
const assertSecurityHeaders = (headers, inputs, serializedJsonLd) => {
|
||||
const required = [
|
||||
"default-src 'self'", "script-src 'self'", "style-src 'self'", "img-src 'self'", "media-src 'self'",
|
||||
"default-src 'self'", "script-src 'self'", "style-src 'self'", "img-src 'self' data:", "media-src 'self'",
|
||||
"font-src 'self'", "connect-src 'none'", "object-src 'none'", "base-uri 'none'", "frame-ancestors 'none'",
|
||||
"form-action 'none'", 'upgrade-insecure-requests', 'X-Content-Type-Options: nosniff',
|
||||
"form-action 'self'", 'upgrade-insecure-requests', 'X-Content-Type-Options: nosniff',
|
||||
'Referrer-Policy: no-referrer', 'X-Frame-Options: DENY',
|
||||
'Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()',
|
||||
];
|
||||
for (const value of required) {
|
||||
if (!headers.includes(value)) throw new Error(`Missing security header policy: ${value}`);
|
||||
}
|
||||
if (/unsafe-inline|unsafe-eval|(?:^|[;\s])\*(?:[;\s]|$)|https?:\/\//iu.test(headers)) {
|
||||
throw new Error('Security header policy contains an unsafe or external source expression.');
|
||||
}
|
||||
const expectedHash = `sha256-${createHash('sha256').update(serializedJsonLd).digest('base64')}`;
|
||||
const hashes = headers.match(/sha256-[A-Za-z0-9+/=]+/gu) ?? [];
|
||||
if (hashes.length !== 1 || hashes[0] !== expectedHash) {
|
||||
|
||||
Reference in New Issue
Block a user