Kritim Yantra
Jul 01, 2025
📸 Introduction: “It’s Just an Image… Right?”
Imagine this:
You’ve built a sleek Laravel web app. Users can upload profile pictures or documents. Everything seems fine… until your server gets hacked.
But how? It was just an image upload!
Welcome to the world of file upload vulnerabilities — one of the most common and dangerous security loopholes in web apps.
In this post, we’ll break down:
Let’s get into it — even if you’re just getting started with Laravel!
Here’s the scary truth: uploading a file means letting someone put code or data on your server.
.php
file disguised as an image. If your server processes it, it can run dangerous code.🧠 Think of it like letting a stranger leave a USB stick inside your locked house. What if it’s not what it seems?
Laravel is secure by default, but upload logic is your responsibility. Common beginner mistakes include:
file->getClientOriginalName()
)Let’s fix that step by step.
$request->validate([
'image' => 'required|image|mimes:jpg,jpeg,png,gif|max:2048'
]);
🔎 Explanation:
image
: Laravel checks for common image extensions.mimes
: Extra layer to limit accepted formats.max:2048
: Limits file size to 2MB.💡 Never trust the file extension alone — attackers can rename
.php
to.jpg
.
Laravel helps, but for extra safety:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $request->file('image')->getPathname());
if (!in_array($mime, ['image/jpeg', 'image/png', 'image/gif'])) {
abort(403, 'Invalid file type');
}
✅ This checks the actual content, not just the name.
$filename = uniqid() . '.' . $request->file('image')->getClientOriginalExtension();
$request->file('image')->move(storage_path('app/uploads'), $filename);
Why?
../../../etc/passwd
Avoid:
public_path('uploads/')
Instead, use:
storage_path('app/uploads/')
And if you want to show the file to users:
return response()->file(storage_path('app/uploads/' . $filename));
📁 This keeps files away from public access and lets you control access with routes and middleware.
$blacklist = ['php', 'exe', 'js', 'sh'];
$ext = strtolower($request->file('upload')->getClientOriginalExtension());
if (in_array($ext, $blacklist)) {
abort(403, 'This file type is not allowed.');
}
Use services like:
Always log who uploaded what and when:
Log::info('User ' . auth()->id() . ' uploaded ' . $filename);
Add rate limiting to avoid abuse:
Route::post('/upload', [UploadController::class, 'store'])->middleware('throttle:10,1');
A popular WordPress plugin in 2023 allowed .php
files to be uploaded via an image upload form.
Result?
Hackers used it to inject malware across thousands of websites.
All because someone didn’t validate file types properly. 😬
🔐 Uploading files is powerful — and dangerous. Here's your beginner security checklist:
File uploads are like front doors to your app.
Would you let anyone walk in without checking who they are?
Start secure. Stay secure.
Use Laravel’s power — and your awareness — to keep your app safe in 2025 and beyond.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google