Skip to content
Merged
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
12 changes: 6 additions & 6 deletions lib/security/csp-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ export function getCSPConfig(request: NextRequest): CSPConfig {
// Enhanced CSP policy with Cloudflare Insights support
const policy = [
"default-src 'self'",
"script-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com",
"script-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com",
"style-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com",
"img-src 'self' data: https: blob:",
"connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co",
"frame-src 'none'",
"connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com",
"frame-src 'self' https://checkout.razorpay.com",
"object-src 'none'",
Comment on lines +48 to 50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Razorpay connect/frame allowances — OK, but consider eval removal.

Allowing https://api.razorpay.com (connect) and https://checkout.razorpay.com (frame) matches Checkout needs. Also consider dropping 'unsafe-eval' from script-src in production.

Apply this diff to remove 'unsafe-eval' here:

-    "script-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com",
+    "script-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com",

If feasible later, also remove 'unsafe-inline' once all inline uses are nonced.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/security/csp-config.ts around lines 48-50, keep the Razorpay connect and
frame allowances as-is but remove 'unsafe-eval' from the script-src CSP in
production; update the CSP builder to conditionally exclude 'unsafe-eval' when
NODE_ENV === 'production' (or use a isProduction flag), preserving other
required sources, and leave a TODO to remove 'unsafe-inline' later when inline
scripts are nonced.

"base-uri 'self'",
"form-action 'self'",
Expand Down Expand Up @@ -77,12 +77,12 @@ export function applyCSPHeaders(response: Response, cspConfig: CSPConfig): Respo
export function getDevelopmentCSP(): string {
return [
"default-src 'self'",
"script-src 'self' 'unsafe-eval' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com",
"script-src 'self' 'unsafe-eval' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com",
"img-src 'self' data: https: blob:",
"connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co",
"frame-src 'none'",
"connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com",
"frame-src 'self' https://checkout.razorpay.com",
"object-src 'none'",
"base-uri 'self'",
"form-action 'self'",
Expand Down
7 changes: 4 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@
"test:local:security": "./scripts/test-ci-local.sh security",
"test:local:build": "./scripts/test-ci-local.sh build",
"test:local:vercel": "./scripts/test-ci-local.sh vercel",
"vercel:setup": "./scripts/setup-vercel-config.sh"
"vercel:setup": "./scripts/setup-vercel-config.sh",
"lighthouse": "lhci autorun",
"lighthouse:local": "lhci autorun --config=lighthouserc.js",
"lighthouse:install": "npm install -g @lhci/cli@0.12.x",
"lighthouse:test": "./scripts/lighthouse-test.sh local",
"lighthouse:custom": "./scripts/lighthouse-test.sh custom"
Comment on lines +34 to +37
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify referenced configs/scripts exist and are executable.

Ensure lighthouserc.js and scripts/lighthouse-test.sh are present and runnable.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Checking Lighthouse config/script presence"
fd -H -a -t f '^lighthouserc\.js$' || true
fd -H -a -t f '^lighthouse-test\.sh$' scripts || true
echo "Check executable bit on scripts/lighthouse-test.sh (if found)"
[ -f scripts/lighthouse-test.sh ] && ls -l scripts/lighthouse-test.sh || echo "scripts/lighthouse-test.sh not found"

Length of output: 176


Add missing scripts/lighthouse-test.sh or update package.json

  • lighthouserc.js found in repo root (lighthouserc.js).
  • scripts/lighthouse-test.sh NOT FOUND — package.json references "./scripts/lighthouse-test.sh". Add the script at scripts/lighthouse-test.sh and make it executable (chmod +x scripts/lighthouse-test.sh), or update package.json to point to the correct existing script.
🤖 Prompt for AI Agents
In package.json around lines 34 to 37, the scripts reference
"./scripts/lighthouse-test.sh" which does not exist; either add a new executable
script at scripts/lighthouse-test.sh (create the file, implement the required
lighthouse invocation, and set executable bit with chmod +x) or update the
package.json entries ("lighthouse:test" and "lighthouse:custom") to point to the
correct existing script path; ensure the chosen script path is relative to the
repo root and that the script is executable in the repo so CI and local runs
succeed.

},
"dependencies": {
"@google/generative-ai": "^0.24.1",
Expand Down
2 changes: 1 addition & 1 deletion vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
Comment on lines 75 to +76
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Avoid sending two CSP headers (static + dynamic).

You also set CSP dynamically in lib/security/csp-config.ts. Two CSP headers combine as an intersection and can cause brittle breakages (and make nonces ineffective if one policy disallows them). Prefer one source of truth.

Apply this diff to remove the static CSP header here and rely on the dynamic CSP:

       {
-        "key": "Content-Security-Policy",
-        "value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
+        // removed: CSP is set dynamically with nonce in lib/security/csp-config.ts
       }

Run to confirm there’s no duplicate CSP setter left:


🏁 Script executed:

#!/bin/bash
rg -n "Content-Security-Policy" -C2
rg -n "applyCSPHeaders|getCSPConfig" -C2

Length of output: 5040


Remove static Content-Security-Policy header from vercel.json — rely on dynamic per-request CSP

vercel.json currently defines a static CSP (vercel.json:75–76); the app also sets CSP per-request in lib/security/csp-config.ts (applyCSPHeaders → response.headers.set at line 70) and in lib/security/api-wrapper.ts (response.headers.set at ~lines 33, 49, 94, 124). Two CSP headers combine by intersection and can break nonces — remove the static header from vercel.json.

🤖 Prompt for AI Agents
In vercel.json around lines 75–76, there is a static Content-Security-Policy
header entry that conflicts with the app's dynamic per-request CSP; remove the
entire "key": "Content-Security-Policy" / "value": ... header object from
vercel.json so CSP is only applied dynamically by lib/security/csp-config.ts and
lib/security/api-wrapper.ts, and then verify there are no other static CSP
entries in configuration before redeploying.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Tighten production CSP: drop 'unsafe-eval' (and ideally 'unsafe-inline') when feasible.

Keeping 'unsafe-eval' (and 'unsafe-inline') in production weakens CSP substantially. Since you already generate nonces, prefer nonce/hashes over 'unsafe-inline', and remove 'unsafe-eval' if not strictly required.

Proposed minimal change now (drop only unsafe-eval):

-"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
+"value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"

If you can, also drop 'unsafe-inline' once all inline scripts/styles are nonced/hashed.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com https://checkout.razorpay.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: blob:; connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co https://api.razorpay.com; frame-src 'self' https://checkout.razorpay.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;"
🤖 Prompt for AI Agents
In vercel.json around line 76, the production Content-Security-Policy currently
includes 'unsafe-eval' (and still allows 'unsafe-inline'); remove 'unsafe-eval'
from the CSP value string now and, if you have implemented nonces/hashes for
inline scripts and styles across the app, replace/remove 'unsafe-inline' as well
and ensure all inline scripts/styles are served with the proper nonce or hashed
values so the policy remains valid.

💡 Verification agent

🧩 Analysis chain

Confirm if additional Razorpay subdomains are needed.

Some integrations use extra hosts (e.g., logging/CDN). If Checkout loads assets from other razorpay domains, you’ll need to whitelist them in script-src/connect-src/frame-src.


🌐 Web query:

Razorpay Checkout CSP: which domains must be allowed for script-src, connect-src, and frame-src?

💡 Result:

Short answer — allow these Razorpay hosts:

Notes: include the exact https:// scheme (and wss:// variant if you observe websocket errors) and add any merchant-specific CDN hostnames you use. Sources: Razorpay integration docs and Razorpay payment-button/iframe implementation notes. [1][2][3]


Add Razorpay CDN domains to the CSP

vercel.json (CSP value at line ~76): whitelist these Razorpay hosts—

🤖 Prompt for AI Agents
In vercel.json around line 76, the Content-Security-Policy string is missing
Razorpay CDN hosts; update the CSP value to include https://cdn.razorpay.com and
https://cdn.razorpay.com/static in script-src, and add https://cdn.razorpay.com
to frame-src; keep https://api.razorpay.com in connect-src and only add any
wss:// Razorpay host if you see websocket errors; also add any merchant-specific
Razorpay/CDN hostnames you use to the appropriate directives.

}
]
}
Expand Down
Loading