Skip to content

Commit

Permalink
address csrf vulnerability
Browse files Browse the repository at this point in the history
improved discord embed support
  • Loading branch information
sergix44 committed Jul 31, 2021
1 parent bff37d6 commit 8402083
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
14 changes: 8 additions & 6 deletions app/Controllers/MediaController.php
Expand Up @@ -41,12 +41,15 @@ public function show(Request $request, Response $response, string $userCode, str

$filesystem = $this->storage;

if (isBot($request->getHeaderLine('User-Agent'))) {
$userAgent = $request->getHeaderLine('User-Agent');
$mime = $filesystem->getMimetype($media->storage_path);

if (isBot($userAgent) && (!isDiscord($userAgent) || (isDiscord($userAgent) && !isDisplayableImage($mime)))) {
return $this->streamMedia($request, $response, $filesystem, $media);
}

try {
$media->mimetype = $filesystem->getMimetype($media->storage_path);
$media->mimetype = $mime;
$size = $filesystem->getSize($media->storage_path);

$type = explode('/', $media->mimetype)[0];
Expand Down Expand Up @@ -114,16 +117,15 @@ public function getRaw(Request $request, Response $response, string $userCode, s
{
$media = $this->getMedia($userCode, $mediaCode, false);

if (!$media || !$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false)) {
if (!$media || (!$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false))) {
throw new HttpNotFoundException($request);
}

if ($ext !== null && pathinfo($media->filename, PATHINFO_EXTENSION) !== $ext) {
throw new HttpBadRequestException($request);
}

// If contains html, return it as text/plain
if (strpos($this->storage->getMimetype($media->storage_path), 'text/htm') !== false) {
if (must_be_escaped($this->storage->getMimetype($media->storage_path))) {
$response = $this->streamMedia($request, $response, $this->storage, $media);
return $response->withHeader('Content-Type', 'text/plain');
}
Expand All @@ -146,7 +148,7 @@ public function download(Request $request, Response $response, string $userCode,
{
$media = $this->getMedia($userCode, $mediaCode, false);

if (!$media || !$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false)) {
if (!$media || (!$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false))) {
throw new HttpNotFoundException($request);
}

Expand Down
4 changes: 2 additions & 2 deletions app/Web/Session.php
Expand Up @@ -26,7 +26,7 @@ public function __construct(string $name, $path = '')
$params = session_get_cookie_params();
session_set_cookie_params(
$params['lifetime'],
$params['path'].'; SameSite=Lax',
$params['path'].'; SameSite=Strict',
$params['domain'],
$params['secure'],
$params['httponly']
Expand All @@ -38,7 +38,7 @@ public function __construct(string $name, $path = '')
'save_path' => $path,
'cookie_httponly' => true,
'gc_probability' => 25,
'cookie_samesite' => 'Lax', // works only for php >= 7.3
'cookie_samesite' => 'Strict', // works only for php >= 7.3
]);

if (!$started) {
Expand Down
49 changes: 47 additions & 2 deletions app/helpers.php
Expand Up @@ -67,8 +67,6 @@ function isDisplayableImage(?string $mime): bool
'image/x-icon',
'image/jpeg',
'image/png',
'image/svg',
'image/svg+xml',
'image/tiff',
'image/webp',
]);
Expand Down Expand Up @@ -345,6 +343,29 @@ function isBot(string $userAgent)
}
}

if (!function_exists('isDiscord')) {
/**
* @param string $userAgent
*
* @return bool
*/
function isDiscord(string $userAgent): bool
{
$bots = [
'discord',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0' // discord image bot
];

foreach ($bots as $bot) {
if (stripos($userAgent, $bot) !== false) {
return true;
}
}

return false;
}
}

if (!function_exists('mime2font')) {
/**
* Convert get the icon from the file mimetype.
Expand Down Expand Up @@ -495,3 +516,27 @@ function platform_mail($mailbox = 'no-reply'): string
return $mailbox.'@'.str_ireplace('www.', '', parse_url(resolve('config')['base_url'], PHP_URL_HOST));
}
}

if (!function_exists('must_be_escaped')) {
/**
* Return the system no-reply mail.
*
* @param $mime
* @return bool
*/
function must_be_escaped($mime): bool
{
$mimes = [
'text/htm',
'image/svg'
];

foreach ($mimes as $m) {
if (stripos($mime, $m) !== false) {
return true;
}
}

return false;
}
}

0 comments on commit 8402083

Please sign in to comment.