address csrf vulnerability
improved discord embed support
This commit is contained in:
parent
bff37d6926
commit
84020830ca
3 changed files with 57 additions and 10 deletions
|
@ -41,12 +41,15 @@ class MediaController extends Controller
|
|||
|
||||
$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];
|
||||
|
@ -114,7 +117,7 @@ class MediaController extends Controller
|
|||
{
|
||||
$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);
|
||||
}
|
||||
|
||||
|
@ -122,8 +125,7 @@ class MediaController extends Controller
|
|||
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');
|
||||
}
|
||||
|
@ -146,7 +148,7 @@ class MediaController extends Controller
|
|||
{
|
||||
$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);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class Session
|
|||
$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']
|
||||
|
@ -38,7 +38,7 @@ class Session
|
|||
'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) {
|
||||
|
|
|
@ -67,8 +67,6 @@ if (!function_exists('isDisplayableImage')) {
|
|||
'image/x-icon',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/svg',
|
||||
'image/svg+xml',
|
||||
'image/tiff',
|
||||
'image/webp',
|
||||
]);
|
||||
|
@ -345,6 +343,29 @@ if (!function_exists('isBot')) {
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -495,3 +516,27 @@ if (!function_exists('platform_mail')) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue