file upload server side check

This commit is contained in:
Yuri Kuznetsov
2022-06-30 15:05:47 +03:00
parent 0fe2ea1d44
commit e8060925a3
3 changed files with 61 additions and 1 deletions

View File

@@ -54,4 +54,17 @@ class MimeType
return $typeList[0] ?? null;
}
public static function matchMimeTypeToAcceptToken(string $mimeType, string $token): bool
{
if ($mimeType === $token) {
return true;
}
if (in_array($token, ['audio/*', 'video/*', 'image/*'])) {
return strpos($mimeType, substr($token, 0, -2)) === 0;
}
return false;
}
}

View File

@@ -283,6 +283,9 @@ class Attachment extends Record
}
}
/**
* @throws Forbidden
*/
private function checkAttachmentType(AttachmentEntity $attachment): void
{
$field = $attachment->getTargetField();
@@ -302,6 +305,42 @@ class Attachment extends Record
return;
}
$name = $attachment->getName() ?? '';
$extension = strtolower(
array_slice(explode('.', $name), -1)[0] ?? ''
);
/** @var string[] */
$accept = $this->metadata->get(['entityDefs', $entityType, 'fields', $field, 'accept']) ?? [];
if ($accept === []) {
return;
}
$mimeType = $this->getMimeTypeUtil()->getMimeTypeByExtension($extension) ??
$attachment->getType();
$found = false;
foreach ($accept as $token) {
if (strtolower($token) === '.' . $extension) {
$found = true;
break;
}
if ($mimeType && MimeType::matchMimeTypeToAcceptToken($mimeType, $token)) {
$found = true;
break;
}
}
if (!$found) {
throw new ForbiddenSilent("Not allowed file type.");
}
}
/**

View File

@@ -41,7 +41,7 @@ class MimeTypeTest extends \PHPUnit\Framework\TestCase
$this->metadata = $this->createMock(Metadata::class);
}
public function testGetMimeTypeByExtension1(): void
public function testGetMimeTypeByExtension(): void
{
$this->metadata
->expects($this->any())
@@ -54,4 +54,12 @@ class MimeTypeTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('text/csv', $util->getMimeTypeByExtension('csv'));
$this->assertEquals('text/csv', $util->getMimeTypeByExtension('CSV'));
}
public function testMatchMimeTypeToAcceptToken(): void
{
$this->assertTrue(MimeType::matchMimeTypeToAcceptToken('text/csv', 'text/csv'));
$this->assertFalse(MimeType::matchMimeTypeToAcceptToken('text/csv', 'text/plain'));
$this->assertTrue(MimeType::matchMimeTypeToAcceptToken('video/mpeg', 'video/*'));
$this->assertFalse(MimeType::matchMimeTypeToAcceptToken('video/mpeg', 'image/*'));
}
}