CVE-2021-4116 (PHP, published 2021-12-15T14:15Z)
Description: value: yetiforcecrm is vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Severity: LOW (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/yetiforcecompany/yetiforcecrm
Files changed:
app/Fields/File.php
config/version.php
languages/en-US/Other/Exceptions.json
Commit message: Improved validation of uploaded files


Vulnerable code:
	 * @param array $path
	public static function loadFromPath($path)
		$instance->name = basename($path);
		$instance->name = $name;
	 * @param bool|string $type
	public function validate($type = false)
			Log::error("Error: {$e->getMessage()} | {$this->getName()} | {$this->getSize()}", __CLASS__);
	 * @param bool|string $type
	public function validateAndSecure($type = false): bool
		if ('image' === $this->getShortMimeType(0) && static::secureImage($this)) {
				throw new \App\Exceptions\DangerousFile('ERR_FILE_PHP_CODE_INJECTION');
		if (
			if (
				$imageSize
				&& (empty($imageInfo['APP1']) || 0 === strpos($imageInfo['APP1'], 'Exif'))
				&& ($exifdata = exif_read_data($this->path)) && !$this->validateImageMetadata($exifdata)
			) {
				throw new \App\Exceptions\DangerousFile('ERR_FILE_PHP_CODE_INJECTION');
	 * Validate image metadata.
	 * @param mixed $data
	private function validateImageMetadata($data)
				if (!$this->validateImageMetadata($value)) {
				return false;
		return true;
					if (!static::secureImage($file)) {
	public static function secureImage(self $file): bool
	'appVersion' => '6.3.5',
    "ERR_FILE_PHP_CODE_INJECTION": "File contains dangerous PHP code and was rejected",

Fixed code:
		if (isset($instance->name)) {
			$instance->name = trim(\App\Purifier::purify($instance->name));
		}
	 * @param string $path
	public static function loadFromPath(string $path)
		$instance->name = trim(\App\Purifier::purify(basename($path)));
		$instance->name = trim(\App\Purifier::purify($name));
	 * @param string|null $type
	public function validate(?string $type = null): bool
			Log::error("Error during file validation: {$this->getName()} | Size: {$this->getSize()}\n {$e->__toString()}", __CLASS__);
	 * @param string|null $type
	public function validateAndSecure(?string $type = null): bool
		if (static::secureFile($this)) {
		if (!$this->validateInjection($this->name)) {
			throw new \App\Exceptions\DangerousFile('ERR_FILE_ILLEGAL_NAME');
		}
				throw new \App\Exceptions\DangerousFile('ERR_FILE_CODE_INJECTION');
		if (\extension_loaded('imagick')) {
			try {
				$img = new \imagick($this->path);
				$this->validateInjection($img->getImageProperties());
			} catch (\Throwable $e) {
				throw new \App\Exceptions\DangerousFile('ERR_FILE_CODE_INJECTION', $e->getCode(), $e);
			}
		} elseif (
			try {
				if (
					$imageSize
					&& (empty($imageInfo['APP1']) || 0 === strpos($imageInfo['APP1'], 'Exif'))
					&& ($exifData = exif_read_data($this->path)) && !$this->validateInjection($exifData)
				) {
					throw new \App\Exceptions\DangerousFile('ERR_FILE_CODE_INJECTION');
				}
			} catch (\Throwable $e) {
				throw new \App\Exceptions\DangerousFile('ERR_FILE_CODE_INJECTION', $e->getCode(), $e);
	 * Validate injection.
	 * @param string|array $data
	private function validateInjection($data): bool
		$return = true;
				if (!$this->validateInjection($value)) {
				$return = false;
			} else {
				\App\Purifier::purifyHtmlEventAttributes($data);
		return $return;
					if (!static::secureFile($file)) {
	public static function secureFile(self $file): bool
		if ('image' !== $file->getShortMimeType(0)) {
			return false;
		}
	'appVersion' => '6.3.6',
    "ERR_FILE_ILLEGAL_NAME": "Illegal file name",
    "ERR_FILE_CODE_INJECTION": "File contains dangerous code and was rejected",