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
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2024-05-25 - Information Disclosure in API Error Handling
**Vulnerability:** The API endpoint `src/app/api/upload/route.ts` logged internal environment variable presence to stdout and returned specific Cloudinary setup instructions and error details to clients in its JSON response.
**Learning:** Detailed API error handling can inadvertently leak server architecture or service configurations to clients. By providing generic user-facing errors, potential attackers learn less about the server's internals.
**Prevention:** Implement standard centralized error handlers or ensure catching blocks never return the raw exception objects/messages or service configuration checks to the client.
26 changes: 8 additions & 18 deletions src/app/api/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ 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
});
// πŸ›‘οΈ Sentinel Security Fix: Do not expose which specific environment variables are missing
console.error('Upload service configuration error: Missing required credentials');
return NextResponse.json(
{ error: 'Cloudinary is not configured. Please set environment variables.' },
// πŸ›‘οΈ Sentinel Security Fix: Provide a generic error message to avoid information disclosure
{ error: 'Upload service unavailable. Please contact administrator.' },
{ status: 500 }
);
}
Expand Down Expand Up @@ -58,20 +56,12 @@ export async function POST(request: NextRequest) {
publicId: uploadResult.public_id,
});
} 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);
// πŸ›‘οΈ Sentinel Security Fix: Log detailed error internally but don't expose stack traces or Cloudinary details to the client
console.error('Upload error:', error?.message || error, error?.error || '');

return NextResponse.json(
errorDetails,
// πŸ›‘οΈ Sentinel Security Fix: Provide a generic error message to the client
{ error: 'Failed to upload image. Please try again later.' },
{ status: 500 }
);
}
Expand Down