Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

## 2024-05-30 - Prevent Information Disclosure in Upload Endpoints
**Vulnerability:** The `/api/upload` endpoint was leaking sensitive internal configuration details (such as the presence or absence of specific Cloudinary environment variables) and detailed third-party service errors (like Cloudinary stack traces and HTTP codes) directly to the client in the 500 error response.
**Learning:** Returning detailed error objects or stack traces from third-party services, or explicit validation checks for server configuration variables, directly to the client exposes internal architectural details that attackers can use to map the backend infrastructure or exploit misconfigurations.
**Prevention:** Always catch exceptions or validation errors internally, log the detailed error for debugging, and return a sanitized, generic error message (e.g., 'Internal server error') to the client.
20 changes: 3 additions & 17 deletions src/app/api/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ export async function POST(request: NextRequest) {
try {
// Verify Cloudinary configuration
if (!process.env.CLOUDINARY_CLOUD_NAME || !process.env.CLOUDINARY_API_KEY || !process.env.CLOUDINARY_API_SECRET) {
console.error('Missing Cloudinary credentials:', {
cloud_name: !!process.env.CLOUDINARY_CLOUD_NAME,
api_key: !!process.env.CLOUDINARY_API_KEY,
api_secret: !!process.env.CLOUDINARY_API_SECRET
});
console.error('Missing Cloudinary credentials.');
return NextResponse.json(
{ error: 'Cloudinary is not configured. Please set environment variables.' },
{ error: 'Internal server error' },
{ status: 500 }
);
}
Expand Down Expand Up @@ -60,18 +56,8 @@ export async function POST(request: NextRequest) {
} catch (error: any) {
console.error('Upload error:', error);

// Return detailed error message
const errorMessage = error?.message || error?.error?.message || 'Failed to upload image';
const errorDetails = {
error: errorMessage,
details: error?.http_code ? `HTTP ${error.http_code}` : undefined,
cloudinaryError: error?.error || undefined
};

console.error('Full error details:', errorDetails);

return NextResponse.json(
errorDetails,
{ error: 'Internal server error' },
{ status: 500 }
);
}
Expand Down