mirror of
https://github.com/getgrav/grav.git
synced 2026-05-06 13:46:33 +02:00
Merge branch 'develop' into feature/media
This commit is contained in:
@@ -11,11 +11,15 @@
|
||||
|
||||
1. [](#new)
|
||||
* Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533)
|
||||
* Added XSS check for uploaded SVG files before they get stored
|
||||
* Fixed phpstan issues (All level 2, Framework level 5)
|
||||
2. [](#bugfix)
|
||||
* Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504)
|
||||
* Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542)
|
||||
* Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540)
|
||||
* Fixed entity sanitization for XSS detection
|
||||
* Fixed avatar save location when `account://` stream points to custom directory
|
||||
* Fixed bug in `Utils::url()` when path contains root
|
||||
|
||||
# v1.7.30
|
||||
## 02/07/2022
|
||||
|
||||
@@ -11,7 +11,7 @@ form:
|
||||
avatar:
|
||||
type: file
|
||||
size: large
|
||||
destination: 'user://accounts/avatars'
|
||||
destination: 'account://avatars'
|
||||
multiple: false
|
||||
random_name: true
|
||||
|
||||
|
||||
@@ -666,7 +666,7 @@ class UserObject extends FlexObject implements UserInterface, Countable
|
||||
// Check for shared media
|
||||
if (!$folder && !$this->getFlexDirectory()->getMediaFolder()) {
|
||||
$this->_loadMedia = false;
|
||||
$folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'user://accounts/avatars';
|
||||
$folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'account://avatars';
|
||||
}
|
||||
|
||||
return $folder;
|
||||
|
||||
@@ -100,6 +100,10 @@ trait MediaUploadTrait
|
||||
'size' => $uploadedFile->getSize(),
|
||||
];
|
||||
|
||||
if ($uploadedFile instanceof FormFlashFile) {
|
||||
$uploadedFile->checkXss();
|
||||
}
|
||||
|
||||
return $this->checkFileMetadata($metadata, $filename, $settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,22 @@ use function is_string;
|
||||
*/
|
||||
class Security
|
||||
{
|
||||
/**
|
||||
* @param string $filepath
|
||||
* @param array|null $options
|
||||
* @return string|null
|
||||
*/
|
||||
public static function detectXssFromSvgFile(string $filepath, array $options = null): ?string
|
||||
{
|
||||
if (file_exists($filepath) && Grav::instance()['config']->get('security.sanitize_svg')) {
|
||||
$content = file_get_contents($filepath);
|
||||
|
||||
return static::detectXss($content, $options);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize SVG string for XSS code
|
||||
*
|
||||
@@ -200,7 +216,7 @@ class Security
|
||||
}, $string);
|
||||
|
||||
// Clean up entities
|
||||
$string = preg_replace('!(�+[0-9]+)!u', '$1;', $string);
|
||||
$string = preg_replace('!(&#[0-9]+);?!u', '$1;', $string);
|
||||
|
||||
// Decode entities
|
||||
$string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
||||
@@ -193,7 +193,7 @@ class User extends Data implements UserInterface
|
||||
*/
|
||||
public function getMediaFolder()
|
||||
{
|
||||
return $this->blueprints()->fields()['avatar']['destination'] ?? 'user://accounts/avatars';
|
||||
return $this->blueprints()->fields()['avatar']['destination'] ?? 'account://avatars';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -134,10 +134,10 @@ abstract class Utils
|
||||
$resource = $locator->findResource($input, false);
|
||||
}
|
||||
} else {
|
||||
$root = $uri->rootUrl();
|
||||
$root = $uri->rootUrl() . '/';
|
||||
|
||||
if (static::startsWith($input, $root)) {
|
||||
$input = static::replaceFirstOccurrence($root, '', $input);
|
||||
$input = static::replaceFirstOccurrence($root, '/', $input);
|
||||
}
|
||||
|
||||
$input = ltrim($input, '/');
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Framework\Form;
|
||||
|
||||
use Grav\Common\Security;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Psr7\Stream;
|
||||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
@@ -182,6 +184,21 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
|
||||
return $this->upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function checkXss(): void
|
||||
{
|
||||
$tmpFile = $this->getTmpFile();
|
||||
$mime = $this->getClientMediaType();
|
||||
if (Utils::contains($mime, 'svg', false)) {
|
||||
$response = Security::detectXssFromSvgFile($tmpFile);
|
||||
if ($response) {
|
||||
throw new RuntimeException(sprintf('SVG file XSS check failed on %s', $response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user