diff --git a/app/Helper.php b/app/Helper.php index 99c807bd..f7fcd5e3 100644 --- a/app/Helper.php +++ b/app/Helper.php @@ -109,3 +109,21 @@ function className($name) { return preg_replace('/[^\p{L}\p{N}]/u', '', $name); } + +/** + * @param string $file + * @return bool + */ +function isImage(string $file):bool +{ + $tempFileName = tempnam("/tmp", "image-check-"); + $handle = fopen($tempFileName, "w"); + + fwrite($handle, $file); + + $size = @getimagesize($tempFileName); + + fclose($handle); + + return is_array($size) && str_starts_with($size['mime'], 'image'); +} diff --git a/app/Http/Controllers/ItemController.php b/app/Http/Controllers/ItemController.php index fd705b0b..20941e7f 100644 --- a/app/Http/Controllers/ItemController.php +++ b/app/Http/Controllers/ItemController.php @@ -18,6 +18,7 @@ use Illuminate\Routing\Redirector; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\URL; +use Illuminate\Validation\ValidationException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; @@ -203,6 +204,7 @@ class ItemController extends Controller $validatedData = $request->validate([ 'title' => 'required|max:255', 'url' => 'required', + 'file' => 'image' ]); if ($request->hasFile('file')) { @@ -219,6 +221,10 @@ class ItemController extends Controller ); $contents = file_get_contents($request->input('icon'), false, stream_context_create($options)); + if (!isImage($contents)) { + throw ValidationException::withMessages(['file' => 'Icon must be an image.']); + } + if ($application) { $icon = $application->icon; } else { diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 2adc7b2b..89af0dcf 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -77,6 +77,10 @@ class SettingsController extends Controller } if ($setting->type === 'image') { + $validatedData = $request->validate([ + 'value' => 'image' + ]); + if (!$request->hasFile('value')) { throw new \Exception( 'file_too_big' diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index d5d95891..1b65a824 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -57,6 +57,7 @@ class TagController extends Controller { $validatedData = $request->validate([ 'title' => 'required|max:255', + 'file' => 'image' ]); if ($request->hasFile('file')) { @@ -129,6 +130,7 @@ class TagController extends Controller { $validatedData = $request->validate([ 'title' => 'required|max:255', + 'file' => 'image' ]); if ($request->hasFile('file')) { diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index d208d847..256cd0d8 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -62,7 +62,7 @@ class UserController extends Controller 'email' => 'required|email', 'password' => 'nullable|confirmed', 'password_confirmation' => 'nullable', - + 'file' => 'image' ]); $user = new User; $user->username = $request->input('username'); @@ -129,6 +129,7 @@ class UserController extends Controller 'email' => 'required|email', 'password' => 'nullable|confirmed', 'password_confirmation' => 'nullable', + 'file' => 'image' ]); //die(print_r($request->all())); diff --git a/tests/Unit/helpers/IsImageTest.php b/tests/Unit/helpers/IsImageTest.php new file mode 100644 index 00000000..0b3d16bc --- /dev/null +++ b/tests/Unit/helpers/IsImageTest.php @@ -0,0 +1,42 @@ +"); + + $this->assertFalse($actual); + } + + /** + * @return void + */ + public function test_isImage_returns_true_when_file_is_image() + { + $file = file_get_contents(__DIR__ . '/fixtures/heimdall-icon-small.png'); + + $actual = isImage($file); + + $this->assertTrue($actual); + } + + /** + * @return void + */ + public function test_isImage_returns_false_when_file_is_php_but_png() + { + $file = file_get_contents(__DIR__ . '/fixtures/heimdall-icon-small-php.php'); + + $actual = isImage($file); + + $this->assertTrue($actual); + } +} diff --git a/tests/Unit/helpers/fixtures/heimdall-icon-small-php.php b/tests/Unit/helpers/fixtures/heimdall-icon-small-php.php new file mode 100644 index 00000000..107f9cd5 Binary files /dev/null and b/tests/Unit/helpers/fixtures/heimdall-icon-small-php.php differ diff --git a/tests/Unit/helpers/fixtures/heimdall-icon-small.png b/tests/Unit/helpers/fixtures/heimdall-icon-small.png new file mode 100644 index 00000000..cff916cb Binary files /dev/null and b/tests/Unit/helpers/fixtures/heimdall-icon-small.png differ