From a7c2201d241e9165dc4efa227f98d421eaa3257c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 05:05:33 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Information=20Disclosure=20in=20Upload=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sanitized Cloudinary configuration error in `src/app/api/upload/route.ts` to prevent disclosing internal variable status - Sanitized upload error response to generic message to prevent leaking Cloudinary object structures to clients - Documented findings in `.jules/sentinel.md` Co-authored-by: GerryK97 <210032986+GerryK97@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ src/app/api/upload/route.ts | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 00000000..753c2607 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-21 - Information Disclosure in API Error Responses +**Vulnerability:** The image upload API (`/api/upload`) was returning detailed error messages directly to the client, including the status of environment variables (`CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET`) and raw, unhandled Cloudinary error objects. +**Learning:** Returning raw internal error details to the client can leak sensitive configuration states and infrastructure details, providing an attacker with valuable reconnaissance information. +**Prevention:** Always catch exceptions in API routes and return generic error messages to the client. Detailed error information should be logged strictly on the server side for debugging purposes, avoiding exposure to the end-user. diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 1664e115..ee119eb2 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: 'Upload service is not configured' }, { status: 500 } ); } @@ -58,9 +58,7 @@ export async function POST(request: NextRequest) { publicId: uploadResult.public_id, }); } catch (error: any) { - console.error('Upload error:', error); - - // Return detailed error message + // Return detailed error message internally const errorMessage = error?.message || error?.error?.message || 'Failed to upload image'; const errorDetails = { error: errorMessage, @@ -71,7 +69,7 @@ export async function POST(request: NextRequest) { console.error('Full error details:', errorDetails); return NextResponse.json( - errorDetails, + { error: 'Failed to upload image' }, { status: 500 } ); }