From b2d8773dda85d7458e07d9c7f717279237b4eea5 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 04:54:15 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Information=20Disclosure=20Vulnerabilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed the unauthenticated debug endpoint (`src/app/debug/route.ts`) which leaked critical environment variables, including parts of `MONGODB_URI` and the presence of `NEXTAUTH_SECRET`. Sanitized error handling in `src/app/api/upload/route.ts` to return generic error messages to clients instead of detailed configuration warnings and Cloudinary service errors, while maintaining detailed server-side logging. Added a Sentinel journal entry documenting the learning. Co-authored-by: GerryK97 <210032986+GerryK97@users.noreply.github.com> --- .jules/sentinel.md | 4 ++ src/app/api/upload/route.ts | 6 +-- src/app/debug/route.ts | 100 ------------------------------------ 3 files changed, 7 insertions(+), 103 deletions(-) create mode 100644 .jules/sentinel.md delete mode 100644 src/app/debug/route.ts diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 00000000..0f63a07a --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-16 - Prevent Exposure of Internal Configuration and Service Errors +**Vulnerability:** The application had an unauthenticated debug endpoint (`src/app/debug/route.ts`) that leaked environment variables, including parts of `MONGODB_URI` and the status of `NEXTAUTH_SECRET`. Additionally, the `/api/upload` endpoint exposed internal configuration states (whether Cloudinary environment variables were set) and detailed Cloudinary service errors (`cloudinaryError`) in its JSON responses. +**Learning:** Returning detailed error messages and configuration states in API responses directly to clients can provide attackers with valuable intelligence about the application's infrastructure, dependencies, and internal setup, facilitating further attacks. +**Prevention:** Ensure that all API responses return generic, sanitized error messages (e.g., "Internal server error") to clients. Keep detailed error information, stack traces, and configuration states restricted to secure, internal server logs. Regularly review and remove debug endpoints before deploying to production. diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 1664e115..6855d1dd 100644 --- a/src/app/api/upload/route.ts +++ b/src/app/api/upload/route.ts @@ -12,7 +12,7 @@ export async function POST(request: NextRequest) { api_secret: !!process.env.CLOUDINARY_API_SECRET }); return NextResponse.json( - { error: 'Cloudinary is not configured. Please set environment variables.' }, + { error: 'Internal server error' }, { status: 500 } ); } @@ -60,7 +60,7 @@ export async function POST(request: NextRequest) { } catch (error: any) { console.error('Upload error:', error); - // Return detailed error message + // Return generic error message to client, log details to server const errorMessage = error?.message || error?.error?.message || 'Failed to upload image'; const errorDetails = { error: errorMessage, @@ -71,7 +71,7 @@ export async function POST(request: NextRequest) { console.error('Full error details:', errorDetails); return NextResponse.json( - errorDetails, + { error: 'Internal server error' }, { status: 500 } ); } diff --git a/src/app/debug/route.ts b/src/app/debug/route.ts deleted file mode 100644 index 10a77d99..00000000 --- a/src/app/debug/route.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { NextResponse } from 'next/server'; - -/** - * Simple debug endpoint to check environment variables - * This is a public endpoint (no auth required) - * DELETE THIS FILE BEFORE DEPLOYING TO PRODUCTION - */ -export async function GET() { - const envVars = { - // Authentication - NEXTAUTH_URL: process.env.NEXTAUTH_URL || '❌ NOT SET', - NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET ? '✅ SET (hidden for security)' : '❌ NOT SET', - - // API - NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL || '(empty - using same origin)', - NODE_ENV: process.env.NODE_ENV, - - // Database - MONGODB_URI: process.env.MONGODB_URI - ? `✅ SET (${process.env.MONGODB_URI.substring(0, 60)}...)` - : '❌ NOT SET', - - // Derived info - DEPLOYMENT_URL: process.env.VERCEL_URL - ? `https://${process.env.VERCEL_URL}` - : 'Not on Vercel (localhost)', - }; - - // Check if NEXTAUTH_URL is correct - const nextAuthUrlStatus = () => { - const url = process.env.NEXTAUTH_URL; - if (!url) return '❌ NOT SET - This will cause login to fail!'; - if (url === 'http://localhost:3000') return '⚠️ LOCALHOST - Only for development. Change to your Vercel domain for production!'; - if (!url.startsWith('http')) return '❌ INVALID - Missing http/https'; - if (url.includes('localhost')) return '⚠️ LOCALHOST - Change to Vercel domain for production'; - if (url.includes('vercel.app')) return '✅ LOOKS CORRECT - Production Vercel domain detected'; - return '✅ LOOKS CORRECT'; - }; - - const recommendations = []; - - if (!process.env.NEXTAUTH_URL) { - recommendations.push('❌ CRITICAL: NEXTAUTH_URL not set - Login will fail'); - } else if (process.env.NEXTAUTH_URL === 'http://localhost:3000' && process.env.NODE_ENV === 'production') { - recommendations.push('❌ CRITICAL: NEXTAUTH_URL is localhost on production - Change to your Vercel domain'); - } - - if (!process.env.NEXTAUTH_SECRET) { - recommendations.push('❌ CRITICAL: NEXTAUTH_SECRET not set'); - } - - if (!process.env.MONGODB_URI) { - recommendations.push('❌ CRITICAL: MONGODB_URI not set - Database connection will fail'); - } - - if (recommendations.length === 0) { - recommendations.push('✅ All critical environment variables are set'); - } - - return NextResponse.json( - { - status: '🔍 Environment Variable Check', - timestamp: new Date().toISOString(), - environment: process.env.NODE_ENV, - isDevelopment: process.env.NODE_ENV === 'development', - isProduction: process.env.NODE_ENV === 'production', - isVercel: !!process.env.VERCEL_URL, - - environmentVariables: envVars, - - validationStatus: { - NEXTAUTH_URL: nextAuthUrlStatus(), - NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET ? '✅ SET' : '❌ NOT SET', - MONGODB_URI: process.env.MONGODB_URI ? '✅ SET' : '❌ NOT SET', - }, - - recommendations, - - debugInfo: { - message: 'If you see ❌ (NOT SET) for any variable above, that is the problem', - nextStep: 'Go to Vercel Settings → Environment Variables and set the missing variables', - waitTime: '⏱️ Wait 2-3 minutes after changing variables for Vercel to redeploy', - }, - - // Simple table format - summary: ` -════════════════════════════════════════════════════════════ -ENVIRONMENT VARIABLE STATUS -════════════════════════════════════════════════════════════ -NEXTAUTH_URL: ${envVars.NEXTAUTH_URL} -NEXTAUTH_SECRET: ${process.env.NEXTAUTH_SECRET ? '✅ SET' : '❌ NOT SET'} -MONGODB_URI: ${process.env.MONGODB_URI ? '✅ SET' : '❌ NOT SET'} -NEXT_PUBLIC_API_URL: ${envVars.NEXT_PUBLIC_API_URL} -NODE_ENV: ${process.env.NODE_ENV} -════════════════════════════════════════════════════════════ - `, - }, - { status: 200 } - ); -}