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",