Skip to content

Commit a8e17b4

Browse files
Prevent uploading .php files (#60)
* Prevent uploading .php files * Apply Code Style changes --------- Co-authored-by: duncanmcclean <duncanmcclean@users.noreply.github.com>
1 parent 3230046 commit a8e17b4

File tree

6 files changed

+167
-9
lines changed

6 files changed

+167
-9
lines changed

Diff for: src/Http/Controllers/GuestEntryController.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
use Illuminate\Http\Request;
1414
use Illuminate\Routing\Controller;
1515
use Illuminate\Support\Arr;
16+
use Illuminate\Support\Facades\Validator;
1617
use Illuminate\Support\Str;
18+
use Illuminate\Validation\ValidationException;
1719
use Statamic\Facades\Asset;
1820
use Statamic\Facades\AssetContainer;
1921
use Statamic\Facades\Collection;
@@ -240,8 +242,17 @@ protected function uploadFile(string $key, Field $field, Request $request)
240242
$uploadedFiles = [$uploadedFiles];
241243
}
242244

243-
// Filter out any null values.
244-
$uploadedFiles = collect($uploadedFiles)->filter()->toArray();
245+
$uploadedFiles = collect($uploadedFiles)
246+
->each(function ($file) use ($key) {
247+
if (in_array(trim(strtolower($file->getClientOriginalExtension())), ['php', 'php3', 'php4', 'php5', 'phtml'])) {
248+
$validator = Validator::make([], []);
249+
$validator->errors()->add($key, __('Failed to upload.'));
250+
251+
throw new ValidationException($validator);
252+
}
253+
})
254+
->filter()
255+
->toArray();
245256

246257
/* @var \Illuminate\Http\Testing\File $file */
247258
foreach ($uploadedFiles as $uploadedFile) {

Diff for: src/Http/Requests/DestroyRequest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
class DestroyRequest extends FormRequest
1010
{
11-
use Concerns\WhitelistedCollections,
12-
Concerns\HandleFailedValidation;
11+
use Concerns\HandleFailedValidation,
12+
Concerns\WhitelistedCollections;
1313

1414
public function authorize()
1515
{

Diff for: src/Http/Requests/StoreRequest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
class StoreRequest extends FormRequest
1010
{
1111
use Concerns\AcceptsFormRequests,
12-
Concerns\WhitelistedCollections,
13-
Concerns\HandleFailedValidation;
12+
Concerns\HandleFailedValidation,
13+
Concerns\WhitelistedCollections;
1414

1515
public function authorize()
1616
{

Diff for: src/Http/Requests/UpdateRequest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
class UpdateRequest extends FormRequest
1010
{
1111
use Concerns\AcceptsFormRequests,
12-
Concerns\WhitelistedCollections,
13-
Concerns\HandleFailedValidation;
12+
Concerns\HandleFailedValidation,
13+
Concerns\WhitelistedCollections;
1414

1515
public function authorize()
1616
{

Diff for: tests/Http/Controllers/GuestEntryControllerTest.php

+146
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Support\Facades\Config;
1010
use Illuminate\Support\Facades\Event;
1111
use Illuminate\Support\Facades\File;
12+
use Illuminate\Support\Facades\Storage;
1213
use Spatie\TestTime\TestTime;
1314
use Statamic\Events\EntrySaved;
1415
use Statamic\Facades\Asset;
@@ -18,6 +19,8 @@
1819
use Statamic\Facades\Entry;
1920
use Statamic\Facades\Site;
2021

22+
use function PHPUnit\Framework\assertCount;
23+
2124
beforeEach(function () {
2225
File::deleteDirectory(app('stache')->store('entries')->directory());
2326

@@ -462,6 +465,66 @@
462465
$this->assertIsString($entry->get('attachment'));
463466
});
464467

468+
it('cant store an entry when uploading a PHP file', function () {
469+
AssetContainer::make('assets')->disk('local')->save();
470+
471+
Blueprint::make('comments')
472+
->setNamespace('collections.comments')
473+
->setContents([
474+
'title' => 'Comments',
475+
'sections' => [
476+
'main' => [
477+
'display' => 'main',
478+
'fields' => [
479+
[
480+
'handle' => 'title',
481+
'field' => [
482+
'type' => 'text',
483+
],
484+
],
485+
[
486+
'handle' => 'slug',
487+
'field' => [
488+
'type' => 'slug',
489+
],
490+
],
491+
[
492+
'handle' => 'attachment',
493+
'field' => [
494+
'mode' => 'list',
495+
'container' => 'assets',
496+
'restrict' => false,
497+
'allow_uploads' => true,
498+
'show_filename' => true,
499+
'display' => 'Attachment',
500+
'type' => 'assets',
501+
'icon' => 'assets',
502+
'listable' => 'hidden',
503+
'max_items' => 1,
504+
],
505+
],
506+
],
507+
],
508+
],
509+
])
510+
->save();
511+
512+
Collection::make('comments')->save();
513+
514+
$this
515+
->post(route('statamic.guest-entries.store'), [
516+
'_collection' => encrypt('comments'),
517+
'title' => 'This is great',
518+
'slug' => 'this-is-great',
519+
'attachment' => UploadedFile::fake()->image('foobar.php'),
520+
])
521+
->assertSessionHasErrors('attachment');
522+
523+
assertCount(0, Entry::all());
524+
525+
Storage::disk('local')->assertMissing('assets/foobar.php');
526+
});
527+
465528
it('can store entry and ensure multiple files can be uploaded', function () {
466529
AssetContainer::make('assets')->disk('local')->save();
467530

@@ -1465,6 +1528,89 @@
14651528
$this->assertIsString($entry->get('attachment'));
14661529
});
14671530

1531+
it('cant update entry when uploading a PHP file', function () {
1532+
AssetContainer::make('assets')->disk('local')->save();
1533+
1534+
Blueprint::make('albums')
1535+
->setNamespace('collections.albums')
1536+
->setContents([
1537+
'title' => 'Albums',
1538+
'sections' => [
1539+
'main' => [
1540+
'display' => 'main',
1541+
'fields' => [
1542+
[
1543+
'handle' => 'title',
1544+
'field' => [
1545+
'type' => 'text',
1546+
],
1547+
],
1548+
[
1549+
'handle' => 'artist',
1550+
'field' => [
1551+
'type' => 'text',
1552+
],
1553+
],
1554+
[
1555+
'handle' => 'slug',
1556+
'field' => [
1557+
'type' => 'slug',
1558+
],
1559+
],
1560+
[
1561+
'handle' => 'record_label',
1562+
'field' => [
1563+
'type' => 'text',
1564+
],
1565+
],
1566+
[
1567+
'handle' => 'attachment',
1568+
'field' => [
1569+
'mode' => 'list',
1570+
'container' => 'assets',
1571+
'restrict' => false,
1572+
'allow_uploads' => true,
1573+
'show_filename' => true,
1574+
'display' => 'Attachment',
1575+
'type' => 'assets',
1576+
'icon' => 'assets',
1577+
'listable' => 'hidden',
1578+
'max_items' => 1,
1579+
],
1580+
],
1581+
],
1582+
],
1583+
],
1584+
])
1585+
->save();
1586+
1587+
Collection::make('albums')->save();
1588+
1589+
Entry::make()
1590+
->id('allo-mate-idee')
1591+
->collection('albums')
1592+
->slug('allo-mate')
1593+
->data([
1594+
'title' => 'Allo Mate!',
1595+
'artist' => 'Guvna B',
1596+
])
1597+
->save();
1598+
1599+
$this
1600+
->post(route('statamic.guest-entries.update'), [
1601+
'_collection' => encrypt('albums'),
1602+
'_id' => encrypt('allo-mate-idee'),
1603+
'attachment' => UploadedFile::fake()->image('something.php'),
1604+
])
1605+
->assertSessionHasErrors('attachment');
1606+
1607+
$entry = Entry::find('allo-mate-idee');
1608+
1609+
$this->assertNull($entry->get('attachment'));
1610+
1611+
Storage::disk('local')->assertMissing('something.php');
1612+
});
1613+
14681614
it('can update entry and ensure multiple files can be uploaded', function () {
14691615
AssetContainer::make('assets')->disk('local')->save();
14701616

Diff for: tests/Tags/GuestEntriesTagTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
use DuncanMcClean\GuestEntries\Tags\GuestEntriesTag;
44
use Illuminate\Container\EntryNotFoundException;
55
use Illuminate\Support\Facades\Config;
6-
use function PHPUnit\Framework\assertStringContainsString;
76
use Statamic\Exceptions\CollectionNotFoundException;
87
use Statamic\Facades\Antlers;
98
use Statamic\Facades\Collection;
109
use Statamic\Facades\Entry;
1110
use Statamic\Statamic;
1211
use Statamic\Tags\Tags;
1312

13+
use function PHPUnit\Framework\assertStringContainsString;
14+
1415
$tag = null;
1516

1617
beforeEach(function () use (&$tag) {

0 commit comments

Comments
 (0)