Commit ecf46692 authored by tom's avatar tom

use header instead of meta tag

parent 98e573b8
...@@ -4,6 +4,8 @@ NEXT_PUBLIC_SENTRY_DSN=xxx ...@@ -4,6 +4,8 @@ NEXT_PUBLIC_SENTRY_DSN=xxx
SENTRY_ORG=block-scout SENTRY_ORG=block-scout
SENTRY_PROJECT=new-ui SENTRY_PROJECT=new-ui
SENTRY_AUTH_TOKEN=xxx SENTRY_AUTH_TOKEN=xxx
SENTRY_IGNORE_API_RESOLUTION_ERROR=1
SENTRY_CSP_REPORT_URI=xxx
NEXT_PUBLIC_BLOCKSCOUT_VERSION=xxx NEXT_PUBLIC_BLOCKSCOUT_VERSION=xxx
NEXT_PUBLIC_FOOTER_GITHUB_LINK=https://github.com/blockscout/blockscout NEXT_PUBLIC_FOOTER_GITHUB_LINK=https://github.com/blockscout/blockscout
NEXT_PUBLIC_FOOTER_TWITTER_LINK=https://www.twitter.com/blockscoutcom NEXT_PUBLIC_FOOTER_TWITTER_LINK=https://www.twitter.com/blockscoutcom
......
const getCspPolicy = require('../../lib/csp/getCspPolicy');
async function headers() { async function headers() {
return [ return [
{ {
...@@ -12,6 +14,10 @@ async function headers() { ...@@ -12,6 +14,10 @@ async function headers() {
key: 'X-Content-Type-Options', key: 'X-Content-Type-Options',
value: 'nosniff', value: 'nosniff',
}, },
{
key: 'Content-Security-Policy-Report-Only',
value: getCspPolicy(),
},
], ],
}, },
]; ];
......
import isDev from 'lib/isDev'; const getSupportedNetworks = require('../networks/getSupportedNetworks');
import { NETWORKS } from 'lib/networks';
const KEY_WORDS = {
enum KEY_WORDS { BLOB: 'blob:',
BLOB = 'blob:', DATA: 'data:',
DATA = 'data:', NONE: '\'none\'',
NONE = '\'none\'', REPORT_SAMPLE: `'report-sample'`,
REPORT_SAMPLE = `'report-sample'`, SELF: '\'self\'',
SELF = '\'self\'', STRICT_DYNAMIC: `'strict-dynamic'`,
STRICT_DYNAMIC = `'strict-dynamic'`, UNSAFE_INLINE: '\'unsafe-inline\'',
UNSAFE_INLINE = '\'unsafe-inline\'', UNSAFE_EVAL: '\'unsafe-eval\'',
UNSAFE_EVAL = '\'unsafe-eval\'', };
}
const MAIN_DOMAINS = [ '*.blockscout.com', 'blockscout.com' ]; const MAIN_DOMAINS = [ '*.blockscout.com', 'blockscout.com' ];
const isDev = process.env.NODE_ENV === 'development';
function getNetworksExternalAssets() { function getNetworksExternalAssets() {
const icons = NETWORKS const icons = getSupportedNetworks()
.filter(({ icon }) => typeof icon === 'string') .filter(({ icon }) => typeof icon === 'string')
.map(({ icon }) => new URL(icon as string)); .map(({ icon }) => new URL(icon));
return icons; return icons;
} }
...@@ -34,7 +35,7 @@ function makePolicyMap() { ...@@ -34,7 +35,7 @@ function makePolicyMap() {
KEY_WORDS.SELF, KEY_WORDS.SELF,
// webpack hmr in safari doesn't recognize localhost as 'self' for some reason // webpack hmr in safari doesn't recognize localhost as 'self' for some reason
isDev() ? 'ws://localhost:3000/_next/webpack-hmr' : '', isDev ? 'ws://localhost:3000/_next/webpack-hmr' : '',
// client error monitoring // client error monitoring
'sentry.io', '*.sentry.io', 'sentry.io', '*.sentry.io',
...@@ -45,7 +46,7 @@ function makePolicyMap() { ...@@ -45,7 +46,7 @@ function makePolicyMap() {
// next.js generates and rebuilds source maps in dev using eval() // next.js generates and rebuilds source maps in dev using eval()
// https://github.com/vercel/next.js/issues/14221#issuecomment-657258278 // https://github.com/vercel/next.js/issues/14221#issuecomment-657258278
isDev() ? KEY_WORDS.UNSAFE_EVAL : '', isDev ? KEY_WORDS.UNSAFE_EVAL : '',
...MAIN_DOMAINS, ...MAIN_DOMAINS,
...@@ -96,10 +97,14 @@ function makePolicyMap() { ...@@ -96,10 +97,14 @@ function makePolicyMap() {
'base-uri': [ 'base-uri': [
KEY_WORDS.NONE, KEY_WORDS.NONE,
], ],
'report-uri': [
process.env.SENTRY_CSP_REPORT_URI,
],
}; };
} }
export default function getCspPolicy() { function getCspPolicy() {
const policyMap = makePolicyMap(); const policyMap = makePolicyMap();
const policyString = Object.entries(policyMap) const policyString = Object.entries(policyMap)
...@@ -115,3 +120,5 @@ export default function getCspPolicy() { ...@@ -115,3 +120,5 @@ export default function getCspPolicy() {
return policyString; return policyString;
} }
module.exports = getCspPolicy;
export default function isDev() {
return process.env.NODE_ENV === 'development';
}
...@@ -9,6 +9,7 @@ import optimismIcon from 'icons/networks/optimism.svg'; ...@@ -9,6 +9,7 @@ import optimismIcon from 'icons/networks/optimism.svg';
import poaSokolIcon from 'icons/networks/poa-sokol.svg'; import poaSokolIcon from 'icons/networks/poa-sokol.svg';
import poaIcon from 'icons/networks/poa.svg'; import poaIcon from 'icons/networks/poa.svg';
import rskIcon from 'icons/networks/rsk.svg'; import rskIcon from 'icons/networks/rsk.svg';
import getSupportedNetworks from 'lib/networks/getSupportedNetworks';
// will change later when we agree how to host network icons // will change later when we agree how to host network icons
const ICONS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGElement>>> = { const ICONS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGElement>>> = {
...@@ -25,12 +26,8 @@ const ICONS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGEleme ...@@ -25,12 +26,8 @@ const ICONS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGEleme
}; };
export const NETWORKS: Array<Network> = (() => { export const NETWORKS: Array<Network> = (() => {
try { const networksFromConfig: Array<Network> = getSupportedNetworks();
const networksFromConfig: Array<Network> = JSON.parse(process.env.NEXT_PUBLIC_SUPPORTED_NETWORKS || '[]'); return networksFromConfig.map((network) => ({ ...network, icon: network.icon || ICONS[`${ network.type }/${ network.subType }`] }));
return networksFromConfig.map((network) => ({ ...network, icon: network.icon || ICONS[`${ network.type }/${ network.subType }`] }));
} catch (error) {
return [];
}
})(); })();
// for easy env creation // for easy env creation
......
function getSupportedNetworks() {
try {
return JSON.parse(process.env.NEXT_PUBLIC_SUPPORTED_NETWORKS || '[]');
} catch (error) {
return [];
}
}
module.exports = getSupportedNetworks;
...@@ -2,7 +2,6 @@ import { ColorModeScript } from '@chakra-ui/react'; ...@@ -2,7 +2,6 @@ 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 {
...@@ -14,10 +13,6 @@ class MyDocument extends Document { ...@@ -14,10 +13,6 @@ 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"
/> />
<meta
httpEquiv="Content-Security-Policy"
content={ getCspPolicy() }
/>
</Head> </Head>
<body> <body>
<ColorModeScript initialColorMode={ theme.config.initialColorMode }/> <ColorModeScript initialColorMode={ theme.config.initialColorMode }/>
......
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