Skip to content

Commit a27095a

Browse files
committed
pkp#7916 Replaced html purifier with symfony html sanitizer
1 parent ad45913 commit a27095a

File tree

3 files changed

+869
-506
lines changed

3 files changed

+869
-506
lines changed

classes/core/PKPString.php

+58-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919

2020
use HTMLPurifier;
2121
use HTMLPurifier_Config;
22+
use Illuminate\Support\Str;
2223
use PKP\config\Config;
24+
use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
25+
use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
2326
use Stringy\Stringy;
2427

2528
class PKPString
@@ -406,16 +409,62 @@ public static function getAmbiguousExtensionsMap()
406409
*/
407410
public static function stripUnsafeHtml($input, $configKey = 'allowed_html')
408411
{
409-
static $purifier;
410-
if (!isset($purifier)) {
411-
$config = HTMLPurifier_Config::createDefault();
412-
$config->set('Core.Encoding', 'utf-8');
413-
$config->set('HTML.Doctype', 'HTML 4.01 Transitional');
414-
$config->set('HTML.Allowed', Config::getVar('security', $configKey));
415-
$config->set('Cache.SerializerPath', 'cache');
416-
$purifier = new HTMLPurifier($config);
412+
// static $purifier;
413+
// if (!isset($purifier)) {
414+
// $config = HTMLPurifier_Config::createDefault();
415+
// $config->set('Core.Encoding', 'utf-8');
416+
// $config->set('HTML.Doctype', 'HTML 4.01 Transitional');
417+
// $config->set('HTML.Allowed', Config::getVar('security', $configKey));
418+
// $config->set('Cache.SerializerPath', 'cache');
419+
// $purifier = new HTMLPurifier($config);
420+
// }
421+
// return $purifier->purify((string) $input);
422+
423+
static $sanitizer;
424+
static $allowedTagToAttributeMap;
425+
426+
if (!isset($htmlTagToAttributeMap)) {
427+
Str::of(Config::getVar('security', $configKey))
428+
->explode(',')
429+
->each(function(string $allowedTagWithAttr) use (&$allowedTagToAttributeMap) {
430+
431+
// Extract the tag itself (e.g. div, p, a ...)
432+
preg_match('/\[[^][]+]\K|\w+/', $allowedTagWithAttr, $matches);
433+
$allowedTag = collect($matches)->first();
434+
435+
// Extract the attributes associated with tag (e.g. class, href ...)
436+
preg_match("/\[([^\]]*)\]/", $allowedTagWithAttr, $matches);
437+
$allowedAttributes = collect($matches)->last();
438+
439+
if($allowedTag) {
440+
$allowedTagToAttributeMap[$allowedTag] = Str::of($allowedAttributes)
441+
->explode('|')
442+
->filter()
443+
->toArray();
444+
}
445+
});
417446
}
418-
return $purifier->purify((string) $input);
447+
448+
if(!isset($sanitizer)) {
449+
450+
$config = (new HtmlSanitizerConfig())
451+
->allowLinkSchemes(['https', 'http', 'mailto'])
452+
->allowMediaSchemes(['https', 'http']);
453+
454+
collect($allowedTagToAttributeMap)
455+
->each(function(array $attributes, string $tag) use (&$config){
456+
$config = $config->allowElement($tag, $attributes);
457+
});
458+
459+
$sanitizer = new HtmlSanitizer($config);
460+
}
461+
462+
return $sanitizer->sanitize(
463+
strip_tags(
464+
$input,
465+
array_keys($allowedTagToAttributeMap)
466+
)
467+
);
419468
}
420469

421470
/**

composer.json

+23-23
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
{
22
"require": {
3-
"ralouphie/getallheaders": "*",
4-
"components/jqueryui": "1.*",
3+
"adodb/adodb-php": "v5.20.18",
54
"components/jquery": "^3.5",
6-
"wikimedia/less.php": "3.*",
7-
"phpmailer/phpmailer": "6.*",
8-
"smarty/smarty": "4.*",
9-
"ezyang/htmlpurifier": "4.*",
10-
"moxiecode/plupload": "2.*",
11-
"tinymce/tinymce": "^5.7",
12-
"michelf/php-markdown": "1.*",
13-
"slim/slim": "3.*",
14-
"pimple/pimple": "3.*",
15-
"laravel/framework": "^9.0",
5+
"components/jqueryui": "1.*",
6+
"composer/semver": "^3.3",
7+
"cweagans/composer-patches": "^1.7",
8+
"dflydev/base32-crockford": "^1.0",
9+
"doctrine/dbal": "^3.5",
10+
"elcobvg/laravel-opcache": "^0.5.0",
1611
"firebase/php-jwt": "5.*",
17-
"adodb/adodb-php": "v5.20.18",
12+
"geoip2/geoip2": "~2.0",
1813
"gettext/gettext": "5.*",
19-
"sokil/php-isocodes": "^4.1",
20-
"doctrine/dbal": "^3.5",
14+
"gettext/translator": "1.*",
2115
"guzzlehttp/guzzle": "^7.0",
16+
"kevinlebrun/colors.php": "^1.0",
17+
"laravel/framework": "^9.0",
2218
"league/flysystem": "^3.0",
2319
"league/flysystem-sftp-v3": "^3.0",
24-
"cweagans/composer-patches": "^1.7",
25-
"kevinlebrun/colors.php": "^1.0",
20+
"michelf/php-markdown": "1.*",
21+
"moxiecode/plupload": "2.*",
22+
"phpmailer/phpmailer": "6.*",
23+
"pimple/pimple": "3.*",
24+
"ralouphie/getallheaders": "*",
25+
"slim/slim": "3.*",
26+
"smarty/smarty": "4.*",
27+
"sokil/php-isocodes": "^4.1",
28+
"sokil/php-isocodes-db-i18n": "^4.0",
29+
"symfony/html-sanitizer": "^6.2",
2630
"symfony/mailer": "^6.0",
27-
"gettext/translator": "1.*",
28-
"elcobvg/laravel-opcache": "^0.5.0",
29-
"composer/semver": "^3.3",
30-
"dflydev/base32-crockford": "^1.0",
31-
"geoip2/geoip2": "~2.0",
31+
"tinymce/tinymce": "^5.7",
3232
"voku/stringy": "^6.5",
33-
"sokil/php-isocodes-db-i18n": "^4.0"
33+
"wikimedia/less.php": "3.*"
3434
},
3535
"require-dev": {
3636
"phpunit/phpunit": "~9",

0 commit comments

Comments
 (0)