Commit 155948f3 authored by tom's avatar tom

rewrite

parent a82753c7
const getCspPolicy = require('./getCspPolicy');
async function headers() { async function headers() {
return [ return [
{ {
source: '/:path*', source: '/:path*',
headers: [ headers: [
// security headers from here - https://nextjs.org/docs/advanced-features/security-headers
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{ {
key: 'Content-Security-Policy', key: 'X-Content-Type-Options',
value: getCspPolicy(), value: 'nosniff',
}, },
], ],
}, },
......
const CONSTS = { import isDev from 'lib/isDev';
BLOB: 'blob:',
DATA: 'data:', enum KEY_WORDS {
NONE: '\'none\'', BLOB = 'blob:',
REPORT_SAMPLE: `'report-sample'`, DATA = 'data:',
SELF: '\'self\'', NONE = '\'none\'',
STRICT_DYNAMIC: `'strict-dynamic'`, REPORT_SAMPLE = `'report-sample'`,
UNSAFE_INLINE: '\'unsafe-inline\'', SELF = '\'self\'',
UNSAFE_EVAL: '\'unsafe-eval\'', STRICT_DYNAMIC = `'strict-dynamic'`,
}; UNSAFE_INLINE = '\'unsafe-inline\'',
UNSAFE_EVAL = '\'unsafe-eval\'',
}
const MAIN_DOMAINS = [ '*.blockscout.com', 'blockscout.com' ]; const MAIN_DOMAINS = [ '*.blockscout.com', 'blockscout.com' ];
function makePolicyMap() { function makePolicyMap() {
return { return {
'default-src': [ 'default-src': [
CONSTS.NONE, KEY_WORDS.NONE,
], ],
'connect-src': [ 'connect-src': [
CONSTS.SELF, KEY_WORDS.SELF,
'sentry.io', '*.sentry.io', // client error monitoring
// webpack hmr in safari doesn't recognize localhost 'self' for some reason
isDev() ? 'ws://localhost:3000/_next/webpack-hmr' : '',
// client error monitoring
'sentry.io', '*.sentry.io',
], ],
'script-src': [ 'script-src': [
CONSTS.SELF, KEY_WORDS.SELF,
// next.js generates and rebuilds source maps in dev using eval()
// https://github.com/vercel/next.js/issues/14221#issuecomment-657258278
isDev() ? KEY_WORDS.UNSAFE_EVAL : '',
...MAIN_DOMAINS, ...MAIN_DOMAINS,
CONSTS.UNSAFE_INLINE, // hash of ColorModeScript
CONSTS.UNSAFE_EVAL, '\'sha256-e7MRMmTzLsLQvIy1iizO1lXf7VWYoQ6ysj5fuUzvRwE=\'',
], ],
'style-src': [ 'style-src': [
CONSTS.SELF, KEY_WORDS.SELF,
...MAIN_DOMAINS, ...MAIN_DOMAINS,
// google fonts
'fonts.googleapis.com', 'fonts.googleapis.com',
CONSTS.UNSAFE_INLINE, // yes, it is unsafe as it stands, but
// - we cannot use hashes because all styles are generated dynamically
// - we cannot use nonces since we are not following along SSR path
// - and still there is very small damage that can be cause by CSS-based XSS-attacks
// so we hope we are fine here till the first major incident :)
KEY_WORDS.UNSAFE_INLINE,
], ],
'img-src': [ 'img-src': [
CONSTS.SELF, KEY_WORDS.SELF,
CONSTS.DATA, KEY_WORDS.DATA,
...MAIN_DOMAINS, ...MAIN_DOMAINS,
// github avatars // github avatars
'avatars.githubusercontent.com', 'avatars.githubusercontent.com',
], ],
'font-src': [ 'font-src': [
CONSTS.SELF, KEY_WORDS.DATA,
CONSTS.DATA,
// google fonts // google fonts
'*.gstatic.com', '*.gstatic.com',
'fonts.googleapis.com', 'fonts.googleapis.com',
], ],
'object-src': [
KEY_WORDS.NONE,
],
'base-uri': [
KEY_WORDS.NONE,
],
}; };
} }
function getCspPolicy() { export default function getCspPolicy() {
const policyMap = makePolicyMap(); const policyMap = makePolicyMap();
const policyHeader = Object.entries(policyMap) const policyHeader = Object.entries(policyMap)
...@@ -72,5 +101,3 @@ function getCspPolicy() { ...@@ -72,5 +101,3 @@ function getCspPolicy() {
return policyHeader; return policyHeader;
} }
module.exports = getCspPolicy;
export default function isDev() {
return process.env.NODE_ENV === 'development';
}
...@@ -2,6 +2,7 @@ import { ColorModeScript } from '@chakra-ui/react'; ...@@ -2,6 +2,7 @@ import { ColorModeScript } from '@chakra-ui/react';
import Document, { Html, Head, Main, NextScript } from 'next/document'; import Document, { Html, Head, Main, NextScript } from 'next/document';
import React from 'react'; import React from 'react';
import getCspPolicy from 'lib/csp/getCspPolicy';
import theme from 'theme'; import theme from 'theme';
class MyDocument extends Document { class MyDocument extends Document {
...@@ -13,9 +14,9 @@ class MyDocument extends Document { ...@@ -13,9 +14,9 @@ class MyDocument extends Document {
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
<link <meta
href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,500;0,600;1,400&display=swap" httpEquiv="Content-Security-Policy"
rel="stylesheet" content={ getCspPolicy() }
/> />
</Head> </Head>
<body> <body>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment