Skip to content

Conversation

@Klakurka
Copy link
Member

@Klakurka Klakurka commented Oct 16, 2025

Description

Reported via contact email

Test plan

Forwarded separately.

Summary by CodeRabbit

  • Security
    • Applied global response headers across all routes: X-Frame-Options set to DENY and Content-Security-Policy updated to disallow embedding via frame-ancestors 'none', preventing the app from being displayed in external frames.
  • Chores
    • Minor configuration cleanup to consolidate environment handling while preserving existing behavior.

@Klakurka Klakurka requested a review from chedieck October 16, 2025 23:14
@Klakurka Klakurka self-assigned this Oct 16, 2025
@Klakurka Klakurka added bug Something isn't working enhancement (behind the scenes) Stuff that users won't see labels Oct 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 16, 2025

Walkthrough

Adds an async headers() export and updates next/constants import in next.config.js; the headers() applies to all routes (/(.*)) and returns X-Frame-Options: DENY and Content-Security-Policy: frame-ancestors 'none'. No other config behavior changed.

Changes

Cohort / File(s) Summary
Next.js config
next.config.js
Destructured PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD, and PHASE_PRODUCTION_SERVER from require('next/constants'); added an async headers() export returning route-wide headers for source /(.*) with X-Frame-Options: DENY and Content-Security-Policy: frame-ancestors 'none'. Kept existing outputFileTracing, eslint, typescript, and rewrites unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Browser
  participant NextJS
  Browser->>NextJS: HTTP request (any path)
  Note right of NextJS #F0F7FF: next.config.js async headers() applies to `/(.*)`\nadds security response headers
  NextJS-->>Browser: HTTP response with headers\nX-Frame-Options: DENY\nContent-Security-Policy: frame-ancestors 'none'
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hopped into config, swift and keen,
Closed the frames where prying had been.
DENY in place, CSP says "none",
Safe burrows now for everyone. 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description is substantially incomplete compared to the required template. The critical "Related to #" section linking to an issue is entirely missing. The Description section provides only "Reported via contact email," which conveys no meaningful information about the issue being addressed. The Test plan section states "Forwarded separately," which indicates the test plan exists elsewhere but is not included in the PR description itself. These are core sections that should contain substantive information to help reviewers understand the change, and their absence or vagueness represents a significant gap in the PR documentation. The PR description should be updated to include: the related issue number in the "Related to #" field; a meaningful non-technical and/or technical description of the clickjacking vulnerability being addressed; and an actual test plan describing how the fix was tested or should be tested, rather than referencing external communication. Including this information directly in the PR will ensure proper documentation for future reference and enable reviewers to understand the full context of the changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "Added security headers to prevent clickjacking on sign in" accurately reflects the main change in the changeset. The raw summary confirms that a new async headers() hook has been added that returns X-Frame-Options: DENY and Content-Security-Policy: frame-ancestors 'none' headers—security headers specifically designed to prevent clickjacking attacks. While the headers apply to all paths rather than exclusively the sign-in page, the title appropriately highlights the primary security concern and motivation without being misleading. The title is concise, specific, and clearly communicates the purpose of the change.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/clickjacking-on-signin

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.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
next.config.js (1)

32-42: ESLint formatting issues detected.

Static analysis flagged indentation inconsistencies (expecting 2-space increments matching the existing file style) and a missing space before function parentheses on Line 32.

Apply this diff to fix formatting:

-      async headers() {
-        return [
-          {
-            source: '/(.*)',
-            headers: [
-              { key: 'X-Frame-Options', value: 'DENY' },
-              { key: 'Content-Security-Policy', value: "frame-ancestors 'self'" },
-            ],
-          },
-        ]
-      },
+    async headers () {
+      return [
+        {
+          source: '/(.*)',
+          headers: [
+            { key: 'X-Frame-Options', value: 'DENY' },
+            { key: 'Content-Security-Policy', value: "frame-ancestors 'self'" },
+          ],
+        },
+      ]
+    },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa8263c and b6cee65.

📒 Files selected for processing (1)
  • next.config.js (1 hunks)
🧰 Additional context used
🪛 ESLint
next.config.js

[error] 32-32: Expected indentation of 4 spaces but found 6.

(indent)


[error] 32-32: Missing space before function parentheses.

(space-before-function-paren)


[error] 33-33: Expected indentation of 6 spaces but found 8.

(indent)


[error] 34-34: Expected indentation of 8 spaces but found 10.

(indent)


[error] 35-35: Expected indentation of 10 spaces but found 12.

(indent)


[error] 36-36: Expected indentation of 10 spaces but found 12.

(indent)


[error] 37-37: Expected indentation of 12 spaces but found 14.

(indent)


[error] 38-38: Expected indentation of 12 spaces but found 14.

(indent)


[error] 39-39: Expected indentation of 10 spaces but found 12.

(indent)


[error] 40-40: Expected indentation of 8 spaces but found 10.

(indent)


[error] 41-41: Expected indentation of 6 spaces but found 8.

(indent)


[error] 42-42: Expected indentation of 4 spaces but found 6.

(indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Run Tests
🔇 Additional comments (1)
next.config.js (1)

35-35: Verify that applying clickjacking protection to all routes is intended.

The pattern /(.*) applies these headers globally to every route in the application. Since the PR title mentions "prevent clickjacking on sign in," confirm whether the protection should be scoped specifically to authentication routes (e.g., /signin, /login) or if global application is the desired behavior.

If you need to scope this to specific routes only, here's an example targeting sign-in pages:

         return [
           {
-            source: '/(.*)',
+            source: '/(signin|login|auth)/:path*',
             headers: [
               { key: 'X-Frame-Options', value: 'DENY' },
               { key: 'Content-Security-Policy', value: "frame-ancestors 'self'" },
             ],
           },
         ]

Copy link
Contributor

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6cee65 and 452356d.

📒 Files selected for processing (1)
  • next.config.js (1 hunks)
🧰 Additional context used
🪛 ESLint
next.config.js

[error] 32-32: Expected indentation of 4 spaces but found 6.

(indent)


[error] 32-32: Missing space before function parentheses.

(space-before-function-paren)


[error] 33-33: Expected indentation of 6 spaces but found 8.

(indent)


[error] 34-34: Expected indentation of 8 spaces but found 10.

(indent)


[error] 35-35: Expected indentation of 10 spaces but found 12.

(indent)


[error] 36-36: Expected indentation of 10 spaces but found 12.

(indent)


[error] 37-37: Expected indentation of 12 spaces but found 14.

(indent)


[error] 38-38: Expected indentation of 12 spaces but found 14.

(indent)


[error] 39-39: Expected indentation of 10 spaces but found 12.

(indent)


[error] 40-40: Expected indentation of 8 spaces but found 10.

(indent)


[error] 41-41: Expected indentation of 6 spaces but found 8.

(indent)


[error] 42-42: Expected indentation of 4 spaces but found 6.

(indent)

🔇 Additional comments (2)
next.config.js (2)

32-42: Security headers correctly aligned!

The clickjacking protection is now properly configured with both headers using the most restrictive settings (DENY and 'none'). This addresses the contradiction flagged in the previous review.


35-35: No legitimate iframe use cases detected — security headers are appropriate.

Comprehensive codebase search found no iframe elements, postMessage calls, or embedding features. The PayButton Widget reference is an internal UI component, not an embeddable widget. The source: '/(.*)' pattern correctly applies the restrictive headers (X-Frame-Options: DENY and frame-ancestors 'none') globally across all routes, which is appropriate for this payment processing application.

Copy link
Contributor

@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: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 452356d and 259dc55.

📒 Files selected for processing (1)
  • next.config.js (1 hunks)
🧰 Additional context used
🪛 ESLint
next.config.js

[error] 32-32: Missing space before function parentheses.

(space-before-function-paren)


[error] 43-43: Missing space before function parentheses.

(space-before-function-paren)

🔇 Additional comments (2)
next.config.js (2)

3-22: LGTM - Phase-based configuration infrastructure added.

The phase constants and conditional logic are correctly implemented following Next.js patterns. While the phase variables (isDev, isBuild, isProd, isStaging) aren't currently used to conditionally apply the security headers, this provides good infrastructure for future environment-specific configuration.


32-42: Verify that all-routes scope is intentional.

The security headers are correctly configured to prevent clickjacking. However, the PR title mentions "prevent clickjacking on sign in" but the implementation applies these headers to all routes via the /(.*) pattern.

While applying security headers broadly is often recommended as defense-in-depth, please confirm this was intentional and not an oversight. If the headers should only apply to sign-in routes, update the source pattern:

       {
-        source: '/(.*)',
+        source: '/signin/:path*',
         headers: [

Copy link
Contributor

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 259dc55 and 630c706.

📒 Files selected for processing (1)
  • next.config.js (1 hunks)
🔇 Additional comments (1)
next.config.js (1)

32-42: Verify that applying anti-framing headers globally aligns with PR intent.

The codebase search found no current iframe usage, postMessage communication, or integrations requiring iframe embedding. However, the PR title mentions "prevent clickjacking on sign in" while the implementation applies headers globally via source: '/(.*)'.

Confirm whether:

  • The global scope is intentional (if so, this is acceptable)
  • Headers should be scoped to authentication routes only (e.g., /auth/:path*, /signin)

@Klakurka Klakurka merged commit 9acfa66 into master Oct 18, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement (behind the scenes) Stuff that users won't see

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants