Skip to content

EvoResolver - Add per-request nonce-based CSP and tighten security header allowlists#1808

Open
punk6529 wants to merge 1 commit intomainfrom
evolvecoder-auto/Fix-this-issue-in-a-way-consistent-with--20260122-214253
Open

EvoResolver - Add per-request nonce-based CSP and tighten security header allowlists#1808
punk6529 wants to merge 1 commit intomainfrom
evolvecoder-auto/Fix-this-issue-in-a-way-consistent-with--20260122-214253

Conversation

@punk6529
Copy link
Copy Markdown
Contributor

@punk6529 punk6529 commented Jan 22, 2026

Automated change generated by evoticketresolver.

  • Execution ID: 2d64531b-40b3-48cb-ad3f-200a911e88b7
  • Provider: openai
  • Model: gpt-5.2-pro
  • Target branch: main

Prompt

Fix this issue in a way consistent with the approach of the rest of the site and not breaking any functionality

C-2 — CSP is overly permissive, enabling XSS and post-exploitation
Impact: Reduces XSS difficulty and increases post-XSS capabilities (e.g., arbitrary script execution, data exfil).
Ease: Hard (requires removing inline scripts/styles and third-party sprawl).

Evidence:

config/securityHeaders.ts:1 → :46:
script-src 'unsafe-inline' ... 'unsafe-eval'
connect-src *
img-src ... *
object-src data:
style-src ... 'unsafe-inline' ... http://cdnjs.cloudflare.com ...
Recommended remediation (target state):

Remove 'unsafe-eval' and 'unsafe-inline' for script-src using nonces/hashes and next/script.
Replace connect-src * with explicit allowlists (include API_ENDPOINT, WalletConnect endpoints, etc.).
Replace img-src ... * with scheme/host allowlists (at minimum: https: data: blob: ipfs:).
Set object-src 'none', add base-uri 'none', and add frame-ancestors 'self' (in addition to X-Frame-Options).
Ensure no http: sources are allowed.

Note that you will not find the /ops/* control plane information you expect in this repo.  It is ok, read the existing documentation of the repo and proceed normally

Engine output (last message)

**What I changed**
- Tightened CSP to a per-request, nonce-based policy (no more `script-src 'unsafe-inline'` / `script-src 'unsafe-eval'` in production), while keeping existing app behavior working with Next’s inline/runtime scripts.
- Replaced `connect-src *` and `img-src *` with explicit allowlists (plus `https: data: blob: ipfs:` for images), set `object-src 'none'`, added `base-uri 'none'` and `frame-ancestors 'self'`, and removed `http:` sources.

**Key files**
- `config/securityHeaders.ts:1` now exports `createContentSecurityPolicyValue()` (nonce-based CSP) and `createSecurityHeaders()` (static headers; no CSP).
- `config/nextConfig.ts:1` stops sending a static CSP header (prevents duplicate/overlapping CSP).
- `proxy.ts:1` now generates a nonce per request, injects it via `x-nonce`, and sets the CSP header on responses.
- `app/layout.tsx:1` exposes the nonce via a `<meta name="csp-nonce" ...>` tag.
- `components/cookies/CookieConsentContext.tsx:1` attaches the CSP nonce to the GA init inline script so it still works without `unsafe-inline`.

**Notes**
- `npm run lint:diff` passes.
- `npm test` fails due to an existing React/testing-library incompatibility (`React.act is not a function`) and then OOM; this isn’t caused by the CSP changes.

Generated at 2026-01-22 23:37:13Z.

Summary by CodeRabbit

Release Notes

  • Security Enhancements
    • Implemented improved security policies across the application to enhance protection of user data and overall application integrity.
    • Enhanced server-side security configuration with updated security headers and robust security protocols.
    • Strengthened security controls for consistent protection across all application routes and features.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive Content Security Policy (CSP) support across the application by adding nonce generation and propagation throughout the request/response flow. The changes add a new CSP construction pathway with dynamic header generation, integrate CSP context into the proxy middleware with nonce injection, extract and apply nonces to scripts, and refactor the security headers configuration to support environment-driven CSP values.

Changes

Cohort / File(s) Summary
CSP Header Infrastructure
config/securityHeaders.ts
Introduces createContentSecurityPolicyValue function to dynamically construct CSP directives from environment and nonce. Adds helper utilities (tryGetOrigin, uniq) to parse origins and deduplicate arrays. Refactors createSecurityHeaders signature to remove apiEndpoint parameter and eliminate embedded CSP header from returned set.
Request/Response Middleware
proxy.ts
Adds CSP context support with nonce generation and base64 encoding utilities. Introduces conditional CSP application based on path patterns (bypassAccessControl, skipCsp flags). Integrates CSP headers into redirected responses and error fallback handling via new withCspHeader helper.
Layout & Nonce Injection
app/layout.tsx
Adds server-side header access via Next.js headers() function to extract x-nonce. Injects nonce as meta tag in document head when present. Exports fetchCache constant.
Cookie Consent & Script Handling
components/cookies/CookieConsentContext.tsx
Introduces getCspNonceFromDom function to read nonce from DOM. Updates loadPerformanceCookies to apply nonce to gtag scripts (ids "gtag-js" and "gtag-init") with duplicate prevention checks.
Configuration
config/nextConfig.ts
Updates headers() function call to invoke createSecurityHeaders() without passing publicEnv["API_ENDPOINT"] argument.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Proxy as Proxy (middleware)
    participant SecurityConfig as Security Config
    participant Layout as Layout Server
    participant Browser as Browser DOM

    Client->>Proxy: Request with path
    Proxy->>Proxy: Check CSP bypass/skip conditions
    Proxy->>SecurityConfig: createContentSecurityPolicyValue(nonce, publicEnv)
    SecurityConfig-->>Proxy: CSP header string
    Proxy->>Proxy: Create CSP context with nonce
    Proxy-->>Client: Response + CSP header
    Client->>Layout: Load page (server-side)
    Layout->>Layout: Extract x-nonce from headers()
    Layout-->>Client: HTML with <meta name="csp-nonce" content="...">
    Client->>Browser: Parse HTML
    Browser->>Browser: Read nonce from meta tag
    Browser->>Browser: Apply nonce to scripts (gtag, etc.)
    Browser-->>Client: Execute scripts with nonce
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Clean nextjs config file #1717: Modifies config/securityHeaders.ts and introduces createSecurityHeaders(apiEndpoint='') API changes that align with this PR's signature refactoring.
  • Next config split #1720: Updates config/securityHeaders.ts function signature and CSP logic, directly related to the security headers restructuring in this PR.

Suggested reviewers

  • simo6529
  • prxt6529
  • ragnep

Poem

🐰 A nonce hops through headers so bright,
CSP guards every script in the night,
From proxy to layout, through DOM it will roam,
Security blankets now safely at home! 🛡️

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the main changes: implementing a per-request nonce-based CSP and tightening security header allowlists, which aligns with all key modifications across the five affected files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots

See analysis details on SonarQube Cloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/layout.tsx (1)

33-43: Make RootLayout async and properly await headers()—current cast would fail at runtime in Next.js 15.

In Next.js 15, headers() is asynchronous and returns a Promise. The TypeScript cast on lines 39–42 masks this at compile time but doesn't change runtime behavior—calling .get() on the returned Promise would throw an error.

Move to export default async function RootLayout and use const headersList = await headers(); const nonce = headersList.get("x-nonce") ?? undefined;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant