Overview
CVE-2017-14704 describes multiple unrestricted file upload vulnerabilities in Claydip's Laravel Airbnb Clone 1.0 (CWE-434: Unrestricted File Upload). A remote authenticated attacker could craft a file with an executable extension (for example a .php file), upload it via the imageSubmit or proof_submit endpoints, and then access the file directly through a URL under images/profile. This could lead to arbitrary code execution on the server and, depending on the app and server configuration, potential resource abuse or denial of service as a consequence of malicious uploads. While the primary risk here is code execution, unrestricted upload paths also create opportunities for resource misuse (large payloads, rapid repeated requests, and similar patterns) that can strain server resources when not properly constrained. This vulnerability is specifically associated with the described CVE-2017-14704 disclosure and its CWE-434 classification for Unrestricted File Upload.
Affected Versions
Claydip Laravel Airbnb Clone 1.0
Code Fix Example
Laravel API Security Remediation
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
class UploadController extends Controller
{
// Vulnerable pattern (illustrative)
public function uploadVulnerable(Request $request)
{
if ($request->hasFile('image')) {
$file = $request->file('image');
// Directly places uploaded file into a web-accessible directory using original name
$destination = public_path('images/profile');
$file->move($destination, $file->getClientOriginalName());
}
return response()->json(['status' => 'ok']);
}
// Fixed pattern (illustrative)
public function uploadFixed(Request $request)
{
// Validate file is an image and enforce limits
$request->validate([
'image' => 'required|image|mimes:jpeg,png,gif,webp|max:2048',
]);
if ($request->hasFile('image')) {
$file = $request->file('image');
// Use a safe, generated filename to avoid path traversal and name collisions
$filename = Str::random(40) . '.' . $file->getClientOriginalExtension();
// Store outside of the web root (local disk by default). This prevents direct execution
// of uploaded files via a URL. Serve the file through a protected endpoint or a controlled flow.
$path = $file->storeAs('uploads/profile', $filename); // storage/app/uploads/profile/...
// If you need public access later, implement a protected retrieval path (not a direct public URL).
return response()->json(['path' => $path]);
}
return response()->json(['status' => 'no_file']);
}
}
?>