Skip to content

fix build error - #25

Merged
Berget1411 merged 1 commit into
mainfrom
fix-deploy
Mar 30, 2026
Merged

fix build error#25
Berget1411 merged 1 commit into
mainfrom
fix-deploy

Conversation

@Berget1411

Copy link
Copy Markdown
Contributor

No description provided.

@Berget1411
Berget1411 merged commit 38082af into main Mar 30, 2026
1 check passed
@Berget1411
Berget1411 deleted the fix-deploy branch March 30, 2026 07:39
@greptile-apps

greptile-apps Bot commented Mar 30, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a Next.js 15 build error by splitting the dev-access page into a Server Component (page.tsx) that awaits the now-async searchParams prop, and a new Client Component (dev-access-form.tsx) that handles all interactive form logic. The refactor is architecturally correct and the form behaviour is functionally identical to before.

One security issue was found:

  • Open redirect in getNextPath — the guard value.startsWith('/') passes protocol-relative URLs like //evil.com. After a successful unlock, window.location.assign('//evil.com') would redirect the user off-site. The fix is to additionally require !value.startsWith('//').

Confidence Score: 4/5

Safe to merge after fixing the open-redirect guard in getNextPath

The refactor is correct and necessary for Next.js 15 compatibility, but the open-redirect vulnerability in getNextPath is a real security defect that should be resolved before this ships to production

frontend/app/dev-access/page.tsx — specifically the getNextPath validation on line 11

Important Files Changed

Filename Overview
frontend/app/dev-access/page.tsx Converted to async Server Component to resolve Next.js 15 searchParams build error; contains an open-redirect vulnerability in getNextPath that allows protocol-relative URLs (e.g. //evil.com)
frontend/app/dev-access/dev-access-form.tsx New 'use client' component extracted from the old page; form logic, API call, and loading/error states are all correct and unchanged from the previous implementation

Sequence Diagram

sequenceDiagram
    participant Browser
    participant DevAccessPage as DevAccessPage (Server)
    participant DevAccessForm as DevAccessForm (Client)
    participant API as Backend API

    Browser->>DevAccessPage: GET /dev-access?next=/dashboard
    DevAccessPage->>DevAccessPage: await searchParams
    DevAccessPage->>DevAccessPage: getNextPath(next) → "/dashboard"
    DevAccessPage->>Browser: Render DevAccessForm nextPath="/dashboard"

    Browser->>DevAccessForm: User submits password
    DevAccessForm->>API: POST /api/access-gate/unlock { password }
    alt Success
        API-->>DevAccessForm: 200 OK (sets httpOnly cookie)
        DevAccessForm->>Browser: window.location.assign("/dashboard")
    else Failure
        API-->>DevAccessForm: 4xx { detail: "..." }
        DevAccessForm->>Browser: Show error message
    end
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (1): Last reviewed commit: "fix build error" | Re-trigger Greptile

</div>
function getNextPath(rawValue: string | string[] | undefined): string {
const value = Array.isArray(rawValue) ? rawValue[0] : rawValue;
return value?.startsWith('/') ? value : '/';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Open redirect via protocol-relative URL

value.startsWith('/') also returns true for //evil.com. When window.location.assign('//evil.com') is called, browsers treat // as a protocol-relative URL and navigate to https://evil.com, allowing an attacker to craft a link like /dev-access?next=//evil.com that redirects the user to an external site after they authenticate.

Fix by additionally rejecting paths that start with //:

Suggested change
return value?.startsWith('/') ? value : '/';
return value?.startsWith('/') && !value.startsWith('//') ? value : '/';

Fix in Codex Fix in Claude Code Fix in Cursor

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