From 0b969dc18f79a59128fb2321f23794d9afbd1ef3 Mon Sep 17 00:00:00 2001 From: Mike Kh Date: Mon, 9 Sep 2024 13:43:16 +0300 Subject: [PATCH] csp_policy_part_1 --- functions/_middleware.ts | 92 ++++++++++++++++++++++--- pnpm-lock.yaml | 142 +++++++++------------------------------ 2 files changed, 113 insertions(+), 121 deletions(-) diff --git a/functions/_middleware.ts b/functions/_middleware.ts index 9899d867b..965a61111 100644 --- a/functions/_middleware.ts +++ b/functions/_middleware.ts @@ -55,22 +55,96 @@ const firefoxRewrite: PagesFunction = async ({ request, next }) => { const userAgent = request.headers.get('user-agent')?.toLowerCase() const response = await next() + // ****************************************************** CSP HEADERS DEFAULTS ****************************************************** + + // default headers + // response.headers.set( + // 'Content-Security-Policy', + // "worker-src 'self'; script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' https://*.googletagmanager.com plausible.io static.cloudflareinsights.com *.ens-app-v3.pages.dev https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com 'wasm-unsafe-eval'; frame-ancestors 'self' https://app.safe.global;", + // ) + + // Default policy for all resource types, restricts everything to the same origin ('self'). default-src 'self' + + // Limits worker sources (Service Workers, Web Workers) to the same origin for security. worker-src 'self' + + // Controls where scripts can be loaded from: + // - 'self' allows scripts from the same origin. + // - 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' is a specific inline script allowed by hash. + // - External trusted domains (e.g., Google Tag Manager, Plausible, Cloudflare, ENS, and Intercom). + // - 'wasm-unsafe-eval' allows WebAssembly execution using eval(). + + // Controls where styles (CSS) can be loaded from: + // - 'self' allows styles from the same origin. + // - 'unsafe-inline' permits inline styles (needed in some frameworks like React). + // - Allows external styles from Google Fonts. + + // Limits image sources to: + // - 'self' allows images from the same origin. + // - 'data:' allows inline base64-encoded images (useful for certain cases). + + // Controls where fonts can be loaded from: + // - 'self' allows fonts from the same origin. + // - Allows external fonts from Google Fonts. + + // Disables plugins like Flash for enhanced security. object-src 'none' + + // Ensures that forms can only submit data to the same origin. form-action 'self' + + // Protects against clickjacking by allowing the site to be embedded only in frames on the same origin and on specific trusted domains (e.g., app.safe.global). frame-ancestors 'self' https://app.safe.global; + + // Prevents setting a base URL, reducing the risk of injection attacks via the base element. base-uri 'self' + + // Controls where the browser can make network requests: + // - 'self' allows network requests to the same origin. + // - Specific trusted external domains (e.g., IPFS, Ethereum, Infura) are permitted for API and data fetching. + + // Ensures that all requests are upgraded from HTTP to HTTPS. upgrade-insecure-requests; + + // Blocks any mixed content (e.g., loading HTTP resources on an HTTPS page) to ensure full security. + + const defaultCSP = ` + default-src 'self'; + worker-src 'self'; + script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' https://*.googletagmanager.com plausible.io static.cloudflareinsights.com https://*.ens-app-v3.pages.dev https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com 'wasm-unsafe-eval'; + style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; + img-src 'self' data: https://*.ipfs.io https://ipfs.euc.li ipfs://*; + font-src 'self' https://fonts.googleapis.com; + object-src 'none'; + form-action 'self'; + frame-ancestors 'self' https://app.safe.global; + base-uri 'self'; + connect-src 'self' https://*.ipfs.io https://*.ethereum.org https://mainnet.infura.io https://ipfs.euc.li ipfs://*; + upgrade-insecure-requests; + block-all-mixed-content; + ` + .replace(/\s{2,}/g, ' ') + .trim() + + response.headers.set('Content-Security-Policy', defaultCSP) + + response.headers.set('X-Frame-Options', 'DENY') // Prevent clickjacking + response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload') // Enforce HTTPS + response.headers.set( + 'Permissions-Policy', + 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), fullscreen=()', + ) // Restrict browser features + response.headers.set('Referrer-Policy', 'no-referrer') // Strictest referrer policy + response.headers.set('X-Content-Type-Options', 'nosniff') // Prevent MIME type sniffing + response.headers.set('X-Permitted-Cross-Domain-Policies', 'none') // Restrict cross-domain policies + response.headers.set('Expect-CT', 'max-age=86400, enforce') // Ensure Certificate Transparency + response.headers.set( + 'Cache-Control', + 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0', + ) // Secure cache management + + // ****************************************************** CSP HEADERS FOR FIREFOX DEFAULTS ****************************************************** // firefox CSP exception + metamask script if (userAgent?.includes('gecko/20100101') && userAgent.includes('firefox/')) { - response.headers.set( - 'Content-Security-Policy', - "frame-ancestors 'self' https://app.safe.global;", - ) return new HTMLRewriter() .on('head', new ScriptWriter('/_next/static/chunks/initialise-metamask.js')) .transform(response) } - // default headers - response.headers.set( - 'Content-Security-Policy', - "worker-src 'self'; script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' https://*.googletagmanager.com plausible.io static.cloudflareinsights.com *.ens-app-v3.pages.dev https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com 'wasm-unsafe-eval'; frame-ancestors 'self' https://app.safe.global;", - ) return response } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11053683f..d9af9e0a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -442,33 +442,6 @@ importers: specifier: ^1.0.0-pre.53 version: 1.0.0-pre.53 - .yalc/@ensdomains/thorin: - dependencies: - clsx: - specifier: ^1.1.1 - version: 1.2.1 - focus-visible: - specifier: ^5.2.0 - version: 5.2.0 - lodash: - specifier: ^4.17.21 - version: 4.17.21 - react: - specifier: ^18.2.0 - version: 18.3.1 - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-transition-state: - specifier: ^2.1.1 - version: 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - styled-components: - specifier: ^5.3.6 - version: 5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) - ts-pattern: - specifier: ^4.3.0 - version: 4.3.0 - packages: '@adobe/css-tools@4.3.3': @@ -8313,12 +8286,6 @@ packages: react: ^18.2.0 react-dom: ^18.2.0 - react-transition-state@2.1.1: - resolution: {integrity: sha512-kQx5g1FVu9knoz1T1WkapjUgFz08qQ/g1OmuWGi3/AoEFfS0kStxrPlZx81urjCXdz2d+1DqLpU6TyLW/Ro04Q==} - peerDependencies: - react: ^18.2.0 - react-dom: ^18.2.0 - react-universal-interface@0.6.2: resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} peerDependencies: @@ -10496,10 +10463,10 @@ snapshots: '@babel/helpers': 7.24.6 '@babel/parser': 7.24.6 '@babel/template': 7.24.6 - '@babel/traverse': 7.24.6 + '@babel/traverse': 7.24.6(supports-color@5.5.0) '@babel/types': 7.24.6 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -11657,21 +11624,6 @@ snapshots: '@babel/parser': 7.25.3 '@babel/types': 7.25.2 - '@babel/traverse@7.24.6': - dependencies: - '@babel/code-frame': 7.24.6 - '@babel/generator': 7.24.6 - '@babel/helper-environment-visitor': 7.24.6 - '@babel/helper-function-name': 7.24.6 - '@babel/helper-hoist-variables': 7.24.6 - '@babel/helper-split-export-declaration': 7.24.6 - '@babel/parser': 7.24.6 - '@babel/types': 7.24.6 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.24.6(supports-color@5.5.0)': dependencies: '@babel/code-frame': 7.24.6 @@ -12071,7 +12023,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -12394,7 +12346,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -12408,7 +12360,7 @@ snapshots: '@babel/core': 7.24.6 '@babel/generator': 7.24.6 '@babel/parser': 7.24.6 - '@babel/traverse': 7.24.6 + '@babel/traverse': 7.24.6(supports-color@5.5.0) '@babel/types': 7.24.6 prettier: 3.0.3 semver: 7.6.2 @@ -12708,7 +12660,7 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) semver: 7.6.2 superstruct: 1.0.4 transitivePeerDependencies: @@ -12720,7 +12672,7 @@ snapshots: '@noble/hashes': 1.4.0 '@scure/base': 1.1.6 '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) pony-cause: 2.1.11 semver: 7.6.2 superstruct: 1.0.4 @@ -12797,7 +12749,7 @@ snapshots: '@open-draft/until': 1.0.3 '@types/debug': 4.1.12 '@xmldom/xmldom': 0.8.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) headers-polyfill: 3.2.5 outvariant: 1.4.2 strict-event-emitter: 0.2.8 @@ -13067,7 +13019,7 @@ snapshots: '@puppeteer/browsers@2.2.3': dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.4.0 @@ -13968,7 +13920,7 @@ snapshots: '@truffle/contract-schema@3.4.16': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -13981,7 +13933,7 @@ snapshots: '@truffle/error': 0.2.2 '@truffle/interface-adapter': 0.5.37(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bignumber.js: 7.2.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) ethers: 4.0.49 web3: 1.10.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) web3-core-helpers: 1.10.0 @@ -14000,7 +13952,7 @@ snapshots: '@trufflesuite/chromafi': 3.0.0 bn.js: 5.2.1 chalk: 2.4.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) highlightjs-solidity: 2.0.6 transitivePeerDependencies: - supports-color @@ -14276,7 +14228,7 @@ snapshots: '@typescript-eslint/type-utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.50.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -14294,7 +14246,7 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.50.0 optionalDependencies: typescript: 5.4.5 @@ -14320,7 +14272,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.50.0)(typescript@5.4.5) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.50.0 ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: @@ -14338,7 +14290,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.2 @@ -14352,7 +14304,7 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -14367,7 +14319,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.10.0 '@typescript-eslint/visitor-keys': 7.10.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.4 @@ -15030,7 +14982,7 @@ snapshots: agent-base@7.1.1: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -15335,17 +15287,6 @@ snapshots: transitivePeerDependencies: - '@babel/core' - babel-plugin-styled-components@2.1.4(@babel/core@7.24.6)(styled-components@5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)): - dependencies: - '@babel/helper-annotate-as-pure': 7.24.6 - '@babel/helper-module-imports': 7.24.6 - '@babel/plugin-syntax-jsx': 7.24.6(@babel/core@7.24.6) - lodash: 4.17.21 - picomatch: 2.3.1 - styled-components: 5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) - transitivePeerDependencies: - - '@babel/core' - babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.24.6): dependencies: '@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.24.6) @@ -16760,7 +16701,7 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.50.0): dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) enhanced-resolve: 5.16.1 eslint: 8.50.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.50.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.50.0))(eslint@8.50.0) @@ -16912,7 +16853,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -17420,7 +17361,7 @@ snapshots: follow-redirects@1.15.6(debug@4.3.4): optionalDependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) for-each@0.3.3: dependencies: @@ -17799,7 +17740,7 @@ snapshots: axios: 0.21.4(debug@4.3.4) chalk: 4.1.2 chokidar: 3.6.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) enquirer: 2.4.1 ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) form-data: 4.0.0 @@ -17832,7 +17773,7 @@ snapshots: chalk: 2.4.2 chokidar: 3.6.0 ci-info: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) enquirer: 2.4.1 env-paths: 2.2.1 ethereum-cryptography: 1.2.0 @@ -17990,7 +17931,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -18015,14 +17956,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -20141,7 +20082,7 @@ snapshots: dependencies: '@puppeteer/browsers': 2.2.3 chromium-bidi: 0.5.19(devtools-protocol@0.0.1286932) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) devtools-protocol: 0.0.1286932 ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -20389,11 +20330,6 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-transition-state@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-universal-interface@0.6.2(react@18.3.1)(tslib@2.6.2): dependencies: react: 18.3.1 @@ -21298,24 +21234,6 @@ snapshots: transitivePeerDependencies: - '@babel/core' - styled-components@5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1): - dependencies: - '@babel/helper-module-imports': 7.24.6 - '@babel/traverse': 7.24.6(supports-color@5.5.0) - '@emotion/is-prop-valid': 1.2.2 - '@emotion/stylis': 0.8.5 - '@emotion/unitless': 0.7.5 - babel-plugin-styled-components: 2.1.4(@babel/core@7.24.6)(styled-components@5.3.11(@babel/core@7.24.6)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)) - css-to-react-native: 3.2.0 - hoist-non-react-statics: 3.3.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - shallowequal: 1.1.0 - supports-color: 5.5.0 - transitivePeerDependencies: - - '@babel/core' - styled-jsx@5.1.1(@babel/core@7.24.6)(react@18.3.1): dependencies: client-only: 0.0.1 @@ -21358,7 +21276,7 @@ snapshots: stylelint-processor-styled-components@1.10.0: dependencies: '@babel/parser': 7.24.6 - '@babel/traverse': 7.24.6 + '@babel/traverse': 7.24.6(supports-color@5.5.0) micromatch: 4.0.7 postcss: 7.0.39 transitivePeerDependencies: @@ -21389,7 +21307,7 @@ snapshots: colord: 2.9.3 cosmiconfig: 7.1.0 css-functions-list: 3.2.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) fast-glob: 3.3.2 fastest-levenshtein: 1.0.16 file-entry-cache: 6.0.1