Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

owasp-part-1 #871

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 98 additions & 24 deletions functions/_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ class AttributeModifier {
}
}

class ScriptWriter {
private src: string
// class ScriptWriter {
// private src: string

constructor(src: string) {
this.src = src
}
// constructor(src: string) {
// this.src = src
// }

element(element: Element) {
element.append(`<script src="${this.src}"></script>`, { html: true })
}
}
// element(element: Element) {
// element.append(`<script src="${this.src}"></script>`, { html: true })
// }
// }

// exception for static files
const staticHandler: PagesFunction = async ({ request, next, env }) => {
Expand All @@ -51,26 +51,100 @@ const staticHandler: PagesFunction = async ({ request, next, env }) => {
return next()
}

const firefoxRewrite: PagesFunction = async ({ request, next }) => {
const userAgent = request.headers.get('user-agent')?.toLowerCase()
const firefoxRewrite: PagesFunction = async ({ next }) => {
// const userAgent = request.headers.get('user-agent')?.toLowerCase()
const response = await 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;",
)
return new HTMLRewriter()
.on('head', new ScriptWriter('/_next/static/chunks/initialise-metamask.js'))
.transform(response)
}
// ****************************************************** 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(
'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;",
)
'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/')) {
// return new HTMLRewriter()
// .on('head', new ScriptWriter('/_next/static/chunks/initialise-metamask.js'))
// .transform(response)
// }

return response
}

Expand Down
Loading
Loading