CVE-2023-5564 (PHP, published 2023-10-13T01:15Z)
Description: value: Cross-site Scripting (XSS) - Stored in GitHub repository froxlor/froxlor prior to 2.1.0-dev1.
Severity: nan (CVSS v3 base score: 4.8)
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/froxlor/froxlor
Files changed:
composer.json
composer.lock
lib/Froxlor/System/Markdown.php
lib/Froxlor/UI/Callbacks/Customer.php
lib/Froxlor/UI/Callbacks/Text.php
lib/Froxlor/UI/Panel/FroxlorTwig.php
lng/de.lng.php
lng/en.lng.php
templates/Froxlor/user/index.html.twig
Commit message: enable markdown syntax in custom_notes field

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>


Vulnerable code:
		"erusev/parsedown": "^1.7",
		"amnuts/opcache-gui": "^3.4"
    "content-hash": "1f9acc318c920b38ee8141e74298655a",
            "name": "erusev/parsedown",
            "version": "1.7.4",
                "url": "https://github.com/erusev/parsedown.git",
                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
                "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
                "ext-mbstring": "*",
                "php": ">=5.3.0"
                "phpunit/phpunit": "^4.8.35"
                "psr-0": {
                    "Parsedown": ""
                    "name": "Emanuil Rusev",
                    "email": "hello@erusev.com",
                    "homepage": "http://erusev.com"
            "description": "Parser for Markdown.",
            "homepage": "http://parsedown.org",
                "markdown",
                "parser"
                "issues": "https://github.com/erusev/parsedown/issues",
                "source": "https://github.com/erusev/parsedown/tree/1.7.x"
            "time": "2019-12-30T22:54:17+00:00"
	public static function isLocked(array $attributes)
	public static function hasNote(array $attributes)
		return !empty($attributes['fields']['custom_notes']);
			'body' => nl2br($note)
			new TwigFilter('parsedown', [
				'callParsedown'
	public function callParsedown($string)
		$pd = new Parsedown();
		return $pd->line($string);
			'description' => 'Hier können Notizen je nach Lust und Laune eingetragen werden. Diese werden in der Administrator/Kunden-Übersicht bei dem jeweiligen Benutzer angezeigt.',
			'description' => 'Feel free to put any notes you want/need in here. They will show up in the admin/customer overview for the corresponding user.',
				{% if userinfo.custom_notes is not empty and userinfo.custom_notes_show == 1 %}
									{{ userinfo.custom_notes|nl2br|raw }}
						{% if userinfo.custom_notes is not empty and userinfo.custom_notes_show == 1 %}
									{{ userinfo.custom_notes|nl2br|raw }}

Fixed code:
		"amnuts/opcache-gui": "^3.4",
		"league/commonmark": "^2.4"
    "content-hash": "cf7a156f58ab3f86204a4b4d263621e2",
            "name": "dflydev/dot-access-data",
            "version": "v3.0.2",
                "url": "https://github.com/dflydev/dflydev-dot-access-data.git",
                "reference": "f41715465d65213d644d3141a6a93081be5d3549"
                "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
                "reference": "f41715465d65213d644d3141a6a93081be5d3549",
                "php": "^7.1 || ^8.0"
                "phpstan/phpstan": "^0.12.42",
                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
                "scrutinizer/ocular": "1.6.0",
                "squizlabs/php_codesniffer": "^3.5",
                "vimeo/psalm": "^4.0.0"
            "extra": {
                "branch-alias": {
                    "dev-main": "3.x-dev"
                }
            },
                "psr-4": {
                    "Dflydev\\DotAccessData\\": "src/"
                    "name": "Dragonfly Development Inc.",
                    "email": "info@dflydev.com",
                    "homepage": "http://dflydev.com"
                },
                {
                    "name": "Beau Simensen",
                    "email": "beau@dflydev.com",
                    "homepage": "http://beausimensen.com"
                },
                {
                    "name": "Carlos Frutos",
                    "email": "carlos@kiwing.it",
                    "homepage": "https://github.com/cfrutos"
                },
                {
                    "name": "Colin O'Dell",
                    "email": "colinodell@gmail.com",
                    "homepage": "https://www.colinodell.com"
            "description": "Given a deep data structure, access data by dot notation.",
            "homepage": "https://github.com/dflydev/dflydev-dot-access-data",
                "access",
                "data",
                "dot",
                "notation"
                "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
                "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2"
            "time": "2022-10-27T11:44:00+00:00"
        {
            "name": "league/commonmark",
            "version": "2.4.1",
            "source": {
                "type": "git",
                "url": "https://github.com/thephpleague/commonmark.git",
                "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
                "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
                "shasum": ""
            },
            "require": {
                "ext-mbstring": "*",
                "league/config": "^1.1.1",
                "php": "^7.4 || ^8.0",
                "psr/event-dispatcher": "^1.0",
                "symfony/deprecation-contracts": "^2.1 || ^3.0",
                "symfony/polyfill-php80": "^1.16"
            },
            "require-dev": {
                "cebe/markdown": "^1.0",
                "commonmark/cmark": "0.30.0",
                "commonmark/commonmark.js": "0.30.0",
                "composer/package-versions-deprecated": "^1.8",
                "embed/embed": "^4.4",
                "erusev/parsedown": "^1.0",
                "ext-json": "*",
                "github/gfm": "0.29.0",
                "michelf/php-markdown": "^1.4 || ^2.0",
                "nyholm/psr7": "^1.5",
                "phpstan/phpstan": "^1.8.2",
                "phpunit/phpunit": "^9.5.21",
                "scrutinizer/ocular": "^1.8.1",
                "symfony/finder": "^5.3 | ^6.0",
                "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
                "unleashedtech/php-coding-standard": "^3.1.1",
                "vimeo/psalm": "^4.24.0 || ^5.0.0"
            },
            "suggest": {
                "symfony/yaml": "v2.3+ required if using the Front Matter extension"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "2.5-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "League\\CommonMark\\": "src"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Colin O'Dell",
                    "email": "colinodell@gmail.com",
                    "homepage": "https://www.colinodell.com",
                    "role": "Lead Developer"
                }
            ],
            "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
            "homepage": "https://commonmark.thephpleague.com",
            "keywords": [
                "commonmark",
                "flavored",
                "gfm",
                "github",
                "github-flavored",
                "markdown",
                "md",
                "parser"
            ],
            "support": {
                "docs": "https://commonmark.thephpleague.com/",
                "forum": "https://github.com/thephpleague/commonmark/discussions",
                "issues": "https://github.com/thephpleague/commonmark/issues",
                "rss": "https://github.com/thephpleague/commonmark/releases.atom",
                "source": "https://github.com/thephpleague/commonmark"
            },
            "funding": [
                {
                    "url": "https://www.colinodell.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://www.paypal.me/colinpodell/10.00",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/colinodell",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/league/commonmark",
                    "type": "tidelift"
                }
            ],
            "time": "2023-08-30T16:55:00+00:00"
        },
        {
            "name": "league/config",
            "version": "v1.2.0",
            "source": {
                "type": "git",
                "url": "https://github.com/thephpleague/config.git",
                "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
                "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
                "shasum": ""
            },
            "require": {
                "dflydev/dot-access-data": "^3.0.1",
                "nette/schema": "^1.2",
                "php": "^7.4 || ^8.0"
            },
            "require-dev": {
                "phpstan/phpstan": "^1.8.2",
                "phpunit/phpunit": "^9.5.5",
                "scrutinizer/ocular": "^1.8.1",
                "unleashedtech/php-coding-standard": "^3.1",
                "vimeo/psalm": "^4.7.3"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-main": "1.2-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "League\\Config\\": "src"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause"
            ],
            "authors": [
                {
                    "name": "Colin O'Dell",
                    "email": "colinodell@gmail.com",
                    "homepage": "https://www.colinodell.com",
                    "role": "Lead Developer"
                }
            ],
            "description": "Define configuration arrays with strict schemas and access values with dot notation",
            "homepage": "https://config.thephpleague.com",
            "keywords": [
                "array",
                "config",
                "configuration",
                "dot",
                "dot-access",
                "nested",
                "schema"
            ],
            "support": {
                "docs": "https://config.thephpleague.com/",
                "issues": "https://github.com/thephpleague/config/issues",
                "rss": "https://github.com/thephpleague/config/releases.atom",
                "source": "https://github.com/thephpleague/config"
            },
            "funding": [
                {
                    "url": "https://www.colinodell.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://www.paypal.me/colinpodell/10.00",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/colinodell",
                    "type": "github"
                }
            ],
            "time": "2022-12-11T20:36:23+00:00"
        },
        {
            "name": "nette/schema",
            "version": "v1.2.4",
            "source": {
                "type": "git",
                "url": "https://github.com/nette/schema.git",
                "reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/nette/schema/zipball/c9ff517a53903b3d4e29ec547fb20feecb05b8ab",
                "reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab",
                "shasum": ""
            },
            "require": {
                "nette/utils": "^2.5.7 || ^3.1.5 ||  ^4.0",
                "php": "7.1 - 8.3"
            },
            "require-dev": {
                "nette/tester": "^2.3 || ^2.4",
                "phpstan/phpstan-nette": "^1.0",
                "tracy/tracy": "^2.7"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "1.2-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause",
                "GPL-2.0-only",
                "GPL-3.0-only"
            ],
            "authors": [
                {
                    "name": "David Grudl",
                    "homepage": "https://davidgrudl.com"
                },
                {
                    "name": "Nette Community",
                    "homepage": "https://nette.org/contributors"
                }
            ],
            "description": "📐 Nette Schema: validating data structures against a given Schema.",
            "homepage": "https://nette.org",
            "keywords": [
                "config",
                "nette"
            ],
            "support": {
                "issues": "https://github.com/nette/schema/issues",
                "source": "https://github.com/nette/schema/tree/v1.2.4"
            },
            "time": "2023-08-05T18:56:25+00:00"
        },
        {
            "name": "nette/utils",
            "version": "v3.2.10",
            "source": {
                "type": "git",
                "url": "https://github.com/nette/utils.git",
                "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/nette/utils/zipball/a4175c62652f2300c8017fb7e640f9ccb11648d2",
                "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2 <8.4"
            },
            "conflict": {
                "nette/di": "<3.0.6"
            },
            "require-dev": {
                "jetbrains/phpstorm-attributes": "dev-master",
                "nette/tester": "~2.0",
                "phpstan/phpstan": "^1.0",
                "tracy/tracy": "^2.3"
            },
            "suggest": {
                "ext-gd": "to use Image",
                "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
                "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
                "ext-json": "to use Nette\\Utils\\Json",
                "ext-mbstring": "to use Strings::lower() etc...",
                "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
                "ext-xml": "to use Strings::length() etc. when mbstring is not available"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "3.2-dev"
                }
            },
            "autoload": {
                "classmap": [
                    "src/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "BSD-3-Clause",
                "GPL-2.0-only",
                "GPL-3.0-only"
            ],
            "authors": [
                {
                    "name": "David Grudl",
                    "homepage": "https://davidgrudl.com"
                },
                {
                    "name": "Nette Community",
                    "homepage": "https://nette.org/contributors"
                }
            ],
            "description": "🛠  Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
            "homepage": "https://nette.org",
            "keywords": [
                "array",
                "core",
                "datetime",
                "images",
                "json",
                "nette",
                "paginator",
                "password",
                "slugify",
                "string",
                "unicode",
                "utf-8",
                "utility",
                "validation"
            ],
            "support": {
                "issues": "https://github.com/nette/utils/issues",
                "source": "https://github.com/nette/utils/tree/v3.2.10"
            },
            "time": "2023-07-30T15:38:18+00:00"
        },
        {
            "name": "psr/event-dispatcher",
            "version": "1.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/event-dispatcher.git",
                "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
                "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "1.0.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\EventDispatcher\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "http://www.php-fig.org/"
                }
            ],
            "description": "Standard interfaces for event handling.",
            "keywords": [
                "events",
                "psr",
                "psr-14"
            ],
            "support": {
                "issues": "https://github.com/php-fig/event-dispatcher/issues",
                "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
            },
            "time": "2019-01-08T18:20:26+00:00"
        },
<?php

/**
 * This file is part of the Froxlor project.
 * Copyright (c) 2010 the Froxlor Team (see authors).
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can also view it online at
 * https://files.froxlor.org/misc/COPYING.txt
 *
 * @copyright  the authors
 * @author     Froxlor team <team@froxlor.org>
 * @license    https://files.froxlor.org/misc/COPYING.txt GPLv2
 */

namespace Froxlor\System;

use League\CommonMark\Exception\CommonMarkException;
use League\CommonMark\GithubFlavoredMarkdownConverter;

class Markdown
{

	private static $converter = null;

	public static function converter(): ?GithubFlavoredMarkdownConverter
	{
		if (is_null(self::$converter)) {
			self::$converter = new GithubFlavoredMarkdownConverter([
				'html_input' => 'strip',
				'allow_unsafe_links' => false,
			]);
		}
		return self::$converter;
	}

	public static function cleanCustomNotes(string $note = ""): string
	{
		if (!empty($note)) {
			try {
				$note = self::converter()->convert($note)->getContent();
			} catch (CommonMarkException $e) {
				$note = "";
			}
		}
		return $note;
	}
}
use Froxlor\System\Markdown;
	public static function isLocked(array $attributes): bool
	public static function hasNote(array $attributes): bool
		$cleanNote = Markdown::cleanCustomNotes($attributes['fields']['custom_notes'] ?? "");
		return !empty($cleanNote);
use Froxlor\System\Markdown;
			'body' => nl2br(Markdown::cleanCustomNotes($note))
use Froxlor\System\Markdown;
			new TwigFilter('markdown', [
				'callMarkdown'
	public function callMarkdown($string): string
		return Markdown::cleanCustomNotes($string ?? "");
			'description' => 'Hier können Notizen je nach Lust und Laune eingetragen werden. Diese werden in der Administrator/Kunden-Übersicht bei dem jeweiligen Benutzer angezeigt.<br>Markdown ist unterstützt, HTML wird entfernt.',
			'description' => 'Feel free to put any notes you want/need in here. They will show up in the admin/customer overview for the corresponding user.<br>Markdown is supported, HTML will be removed.',
				{% if userinfo.custom_notes|markdown is not empty and userinfo.custom_notes_show == 1 %}
									{{ userinfo.custom_notes|markdown|raw }}
						{% if userinfo.custom_notes|markdown is not empty and userinfo.custom_notes_show == 1 %}
									{{ userinfo.custom_notes|markdown|raw }}