From a0f7bff67ce0cb1dd63c67e50bf23a4ab3c2c81a Mon Sep 17 00:00:00 2001 From: ro Date: Wed, 4 Sep 2024 13:29:06 -0600 Subject: [PATCH] updated sanitizer, fixed render on save the module used to sanitize html is no longer maintained, so updated that methodology to use symfony's very sexy sanitizer checked to make sure render on save was working as well. --- app/Services/Data/ContentService.php | 50 ++---- app/Services/Data/SettingsService.php | 2 +- composer.json | 1 + composer.lock | 245 +++++++++++++++++++++++++- 4 files changed, 261 insertions(+), 37 deletions(-) diff --git a/app/Services/Data/ContentService.php b/app/Services/Data/ContentService.php index d832f8f..e1382cf 100644 --- a/app/Services/Data/ContentService.php +++ b/app/Services/Data/ContentService.php @@ -2,18 +2,16 @@ namespace App\Services\Data; -use HtmlSanitizer\SanitizerBuilder; use League\CommonMark\MarkdownConverter; use League\CommonMark\Environment\Environment; -use HtmlSanitizer\Extension\Basic\BasicExtension; -use HtmlSanitizer\Extension\Listing\ListExtension; -use HtmlSanitizer\Extension\Iframe\IframeExtension; use League\CommonMark\Extension\Table\TableExtension; use League\CommonMark\Extension\Attributes\AttributesExtension; use League\CommonMark\Extension\FrontMatter\FrontMatterExtension; use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; use League\CommonMark\Extension\Strikethrough\StrikethroughExtension; use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter; +use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig; +use Symfony\Component\HtmlSanitizer\HtmlSanitizer; class ContentService { @@ -74,39 +72,21 @@ class ContentService ->parse(file_get_contents($file)); //never trust the front end. clean it up - //add what sanitizer extensions we need manually - $builder = new SanitizerBuilder(); - $builder->registerExtension(new BasicExtension()); - $builder->registerExtension(new IframeExtension()); - $builder->registerExtension(new ListExtension()); - //just add it straight because classname is already in use - $builder->registerExtension(new \HtmlSanitizer\Extension\Table\TableExtension()); - //relative-a and relative-image - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\A\AExtension() - ); - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\Image\ImageExtension() - ); + $soap = (new HtmlSanitizerConfig()) + // Allow "safe" elements and attributes. All scripts will be removed + // as well as other dangerous behaviors like CSS injection + ->allowSafeElements() + ->allowElement('div', ['class', 'title', 'id', 'style']) + ->allowElement('img', ['src', 'alt', 'title', 'class']) + ->allowElement('iframe', ['height', 'width', 'title', 'src']) + ->allowElement('table') + ->allowElement('li') + ->allowRelativeMedias() + ->allowRelativeLinks(); - $detergent = [ - 'extensions' => ['basic', 'list', 'relative-a', 'relative-image', 'iframe', 'table'], - 'tags' => [ - 'div' => [ - 'allowed_attributes' => ['class', 'title', 'id', 'style'], - ], - 'img' => [ - 'allowed_attributes' => ['src', 'alt', 'title', 'class'], - ], - 'iframe' => [ - 'allowed_attributes' => ['height', 'width', 'title', 'src'], - ], - ], - ]; - - $sanitizer = $builder->build($detergent); - $scrubbed = $sanitizer->sanitize($result->getContent()); + $laundry = new HtmlSanitizer($soap); + $scrubbed = $laundry->sanitize($result->getContent()); if (isset($meta['feature'])) { $featureList = explode(',', $meta['feature']); } else { diff --git a/app/Services/Data/SettingsService.php b/app/Services/Data/SettingsService.php index 44ae96c..e4344c1 100644 --- a/app/Services/Data/SettingsService.php +++ b/app/Services/Data/SettingsService.php @@ -73,7 +73,7 @@ class SettingsService public function updatePageIndex() { $this->settings = $this->loadSettings(); - $this->settings['library_stats']['current_index']++; + ++$this->settings['library_stats']['current_index']; $this->docs->writeSettings($this->settings); } diff --git a/composer.json b/composer.json index e8e671c..4b1284c 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "nesbot/carbon": "^2.72", "olegatro/html-sanitizer-relative": "^1.0", "rbdwllr/reallysimplejwt": "^5.0", + "symfony/html-sanitizer": "^7.1", "symfony/yaml": "^7.0", "tgalopin/html-sanitizer": "^1.5" }, diff --git a/composer.lock b/composer.lock index 7647fa9..0ea4016 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "424feb400ac91892d8e2c09246a8e7cf", + "content-hash": "d351256775bf2712cb1d92df36953f50", "packages": [ { "name": "brick/math", @@ -1890,6 +1890,180 @@ ], "time": "2024-01-28T23:22:08+00:00" }, + { + "name": "league/uri", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/bedb6e55eff0c933668addaa7efa1e1f2c417cc4", + "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.3", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.4.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-03-23T07:42:40+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/8d43ef5c841032c87e2de015972c06f3865ef718", + "reference": "8d43ef5c841032c87e2de015972c06f3865ef718", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-03-23T07:42:40+00:00" + }, { "name": "league/uri-parser", "version": "1.4.1", @@ -4320,6 +4494,75 @@ ], "time": "2023-10-31T17:59:56+00:00" }, + { + "name": "symfony/html-sanitizer", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/html-sanitizer.git", + "reference": "737cbaa8082b696d0574afd91b9f471eca67fc65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/737cbaa8082b696d0574afd91b9f471eca67fc65", + "reference": "737cbaa8082b696d0574afd91b9f471eca67fc65", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "league/uri": "^6.5|^7.0", + "masterminds/html5": "^2.7.2", + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HtmlSanitizer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a document's DOM.", + "homepage": "https://symfony.com", + "keywords": [ + "Purifier", + "html", + "sanitizer" + ], + "support": { + "source": "https://github.com/symfony/html-sanitizer/tree/v7.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:55:39+00:00" + }, { "name": "symfony/http-foundation", "version": "v7.0.6",