Skip to content

Commit

Permalink
colocate csp header data
Browse files Browse the repository at this point in the history
  • Loading branch information
TateB committed Dec 16, 2024
1 parent 3c393b9 commit 88cc7e6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 40 deletions.
11 changes: 3 additions & 8 deletions functions/_middleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint max-classes-per-file: "off" */
import { cspOnlyFrameAncestors, cspWithFrameAncestors } from '@app/utils/createCsp'

class ContentModifier {
private newContent: string
Expand Down Expand Up @@ -57,20 +58,14 @@ const firefoxRewrite: PagesFunction = async ({ request, next }) => {

// 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;",
)
response.headers.set('Content-Security-Policy', cspOnlyFrameAncestors)
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=' 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;",
)
response.headers.set('Content-Security-Policy', cspWithFrameAncestors)
return response
}

Expand Down
2 changes: 1 addition & 1 deletion functions/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"include": ["../src/utils/gradient.ts", "./**/*"],
"include": ["../src/utils/createCsp.ts", "./**/*"],
"compilerOptions": {
"noEmit": true,
"target": "ESNext",
Expand Down
66 changes: 35 additions & 31 deletions src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { AppPropsType, AppType } from 'next/dist/shared/lib/utils'
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'

import { cspWithoutFrameAncestors } from '@app/utils/createCsp'

const ipfsPathScript = `
(function () {
const { pathname } = window.location
Expand All @@ -14,6 +16,7 @@ const ipfsPathScript = `
})();
`

// sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=
const hiddenCheckScript = `
if (document.prerendering) {
document.addEventListener('prerenderingchange', () => {
Expand All @@ -34,6 +37,36 @@ const hiddenCheckScript = `
}
`

// sha256-84jekTLuMPFFzbBxEFpoUhJbu81z5uBinvhIKKkAPxg=
const themeSwitcherScript = `
(function () {
function setTheme(newTheme) {
document.documentElement.setAttribute('data-theme', newTheme);
window.__theme = newTheme;
window.__onThemeChange(newTheme);
}
window.__onThemeChange = function () {};
window.__setPreferredTheme = function (newTheme) {
setTheme(newTheme);
try {
localStorage.setItem("theme", JSON.stringify(window.__theme));
} catch (err) {}
};
const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
darkQuery.addListener(function (event) {
window.__setPreferredTheme(event.matches ? "dark" : "light");
});
let preferredTheme;
try {
preferredTheme = JSON.parse(localStorage.getItem("theme"));
} catch (err) {}
setTheme(preferredTheme || (darkQuery.matches ? "dark" : "light"));
})();
`

const makeIPFSURL = (url: string) => {
if (process.env.NEXT_PUBLIC_IPFS) {
return `.${url}`
Expand Down Expand Up @@ -76,41 +109,12 @@ export default class MyDocument extends Document {
<Html data-theme="light">
<Head>
{process.env.NODE_ENV === 'production' && (
<meta
httpEquiv="Content-Security-Policy"
content="worker-src 'self'; script-src 'self' 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc=' 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';"
/>
<meta httpEquiv="Content-Security-Policy" content={cspWithoutFrameAncestors} />
)}
<script dangerouslySetInnerHTML={{ __html: hiddenCheckScript }} />
<script
dangerouslySetInnerHTML={{
__html: `(function () {
function setTheme(newTheme) {
document.documentElement.setAttribute('data-theme', newTheme);
window.__theme = newTheme;
window.__onThemeChange(newTheme);
}
window.__onThemeChange = function () {};
window.__setPreferredTheme = function (newTheme) {
setTheme(newTheme);
try {
localStorage.setItem("theme", JSON.stringify(window.__theme));
} catch (err) {}
};
const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
darkQuery.addListener(function (event) {
window.__setPreferredTheme(event.matches ? "dark" : "light");
});
let preferredTheme;
try {
preferredTheme = JSON.parse(localStorage.getItem("theme"));
} catch (err) {}
setTheme(preferredTheme || (darkQuery.matches ? "dark" : "light"));
})();
`,
__html: themeSwitcherScript,
}}
/>
{process.env.NEXT_PUBLIC_IPFS && (
Expand Down
49 changes: 49 additions & 0 deletions src/utils/createCsp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
let csp = ''

// worker-src
csp += 'worker-src'
// only self worker/service worker
csp += " 'self'"
// end worker-src
csp += ';'

// script-src
csp += ' script-src'
// allow self
csp += " 'self'"
// allow plausible script
csp += ' plausible.io'
// allow cloudflare analytics script
csp += ' static.cloudflareinsights.com'
// allow loading from the pages domain for this app
csp += ' *.ens-app-v3.pages.dev'
// allow intercom scripts
csp += ' https://app.intercom.io'
csp += ' https://widget.intercom.io'
csp += ' https://js.intercomcdn.com'
// allow inline wasm evaluation
csp += ' wasm-unsafe-eval'
// INLINE SCRIPT HASHES
// hiddenCheckScript
csp += " 'sha256-UyYcl+sKCF/ROFZPHBlozJrndwfNiC5KT5ZZfup/pPc='"
// themeSwitcherScript
csp += " 'sha256-84jekTLuMPFFzbBxEFpoUhJbu81z5uBinvhIKKkAPxg='"
// end script-src
csp += ';'

// for use with csp meta tag
export const cspWithoutFrameAncestors = csp

let frameAncestors = ''

// frame-ancestors
frameAncestors += 'frame-ancestors'
// allow self
frameAncestors += " 'self'"
// allow safe wallet
frameAncestors += ' https://app.safe.global'
// end frame-ancestors
frameAncestors += ';'

export const cspOnlyFrameAncestors = frameAncestors
export const cspWithFrameAncestors = `${csp} ${frameAncestors}`

0 comments on commit 88cc7e6

Please sign in to comment.