Describe the bug
The /api/github route handler (app/api/github/route.ts, line 255) returns the raw error message from upstream failures directly to the HTTP client in the default 500 fallback:
// Default fallback
const errMessage = getSafeErrorMessage(error);
return NextResponse.json({ error: errMessage }, { status: 500 });
The getSafeErrorMessage helper traverses the full error.cause chain (up to 10 levels deep) and returns whatever string it finds. In practice this can expose:
- Internal Node.js module paths from stack traces (e.g.
Cannot read properties of undefined (reading 'login') at /var/task/lib/github.js:843:22)
- Raw GitHub API response bodies containing repository metadata
- Internal fetch error details such as
connect ECONNREFUSED 127.0.0.1:27017 that reveal infrastructure topology
No sanitisation or allowlist is applied before the string is serialised into the JSON response. Any caller who triggers a 500 can read these details.
Steps to Reproduce
- Send a request to
/api/github?username=<valid_user> while the application's internal GitHub token is intentionally invalid or revoked.
- Observe the
error field in the 500 JSON response body — it contains the raw Node.js error, not a generic message.
Expected Behavior
The default 500 handler should return a fixed, generic message such as "An unexpected error occurred. Please try again." and log the full error server-side via the existing logger infrastructure. No raw exception detail should ever be forwarded to the caller.
Affected Code
File: app/api/github/route.ts, lines 252–255
// Default fallback
const errMessage = getSafeErrorMessage(error);
return NextResponse.json({ error: errMessage }, { status: 500 });
Impact
Unauthenticated users can enumerate internal infrastructure details by intentionally triggering 500 errors, which assists reconnaissance for targeted attacks against the backend.
Suggested Fix
Replace the raw errMessage in the response with a hardcoded generic string and move the detailed error exclusively to the server-side logger:
logger.error('Unhandled error in /api/github', { error });
return NextResponse.json({ error: 'An unexpected error occurred. Please try again.' }, { status: 500 });
Environment
- Next.js 15 (App Router)
- Deployed on Vercel (production)
Describe the bug
The
/api/githubroute handler (app/api/github/route.ts, line 255) returns the raw error message from upstream failures directly to the HTTP client in the default 500 fallback:The
getSafeErrorMessagehelper traverses the fullerror.causechain (up to 10 levels deep) and returns whatever string it finds. In practice this can expose:Cannot read properties of undefined (reading 'login') at /var/task/lib/github.js:843:22)connect ECONNREFUSED 127.0.0.1:27017that reveal infrastructure topologyNo sanitisation or allowlist is applied before the string is serialised into the JSON response. Any caller who triggers a 500 can read these details.
Steps to Reproduce
/api/github?username=<valid_user>while the application's internal GitHub token is intentionally invalid or revoked.errorfield in the 500 JSON response body — it contains the raw Node.js error, not a generic message.Expected Behavior
The default 500 handler should return a fixed, generic message such as
"An unexpected error occurred. Please try again."and log the full error server-side via the existingloggerinfrastructure. No raw exception detail should ever be forwarded to the caller.Affected Code
File:
app/api/github/route.ts, lines 252–255Impact
Unauthenticated users can enumerate internal infrastructure details by intentionally triggering 500 errors, which assists reconnaissance for targeted attacks against the backend.
Suggested Fix
Replace the raw
errMessagein the response with a hardcoded generic string and move the detailed error exclusively to the server-side logger:Environment