diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 00000000..5bd16bb0 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-17 - Error Response Sanitization +**Vulnerability:** Detailed Cloudinary and API service errors were being exposed in the HTTP 500 response bodies in `/api/upload/route.ts`. +**Learning:** Returning `error: error.message` in Catch blocks directly surfaces internal server configurations, credentials status, and backend stack implementation details. +**Prevention:** Always log the detailed error internally (`console.error`) and return a generic `NextResponse.json({ error: "Failed to perform action" })` to the client API response. diff --git a/src/app/api/upload/route.ts b/src/app/api/upload/route.ts index 1664e115..70897221 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 during upload' }, { status: 500 } ); } @@ -60,7 +60,7 @@ export async function POST(request: NextRequest) { } catch (error: any) { console.error('Upload error:', error); - // Return detailed error message + // Construct detailed error message for server logs ONLY const errorMessage = error?.message || error?.error?.message || 'Failed to upload image'; const errorDetails = { error: errorMessage, @@ -70,8 +70,9 @@ export async function POST(request: NextRequest) { console.error('Full error details:', errorDetails); + // Return sanitized generic error message to client return NextResponse.json( - errorDetails, + { error: 'Failed to upload image' }, { status: 500 } ); }