mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-24 23:18:18 +08:00
88c698796b
Fixes a strange issue of HTML tags within script tags being malformed when part of the HTML custom head content due to the PHP parsing we do. DOMDocument seemed to cause this upon load. Adding LIBXML_SCHEMA_CREATE to the ->loadHTML call seems to fix this but not really sure why. Doesn't seem to cause further issues though. Tested with multiple scripts and styles and comments and meta tags. - Also added new testing class to cover. - As part of testing, added new folder within tests to house setting specific tests. For #2914
65 lines
1.7 KiB
PHP
65 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace BookStack\Util;
|
|
|
|
use DOMDocument;
|
|
use DOMElement;
|
|
use DOMNodeList;
|
|
use DOMXPath;
|
|
|
|
class HtmlNonceApplicator
|
|
{
|
|
protected static $placeholder = '[CSP_NONCE_VALUE]';
|
|
|
|
/**
|
|
* Prepare the given HTML content with nonce attributes including a placeholder
|
|
* value which we can target later.
|
|
*/
|
|
public static function prepare(string $html): string
|
|
{
|
|
if (empty($html)) {
|
|
return $html;
|
|
}
|
|
|
|
$html = '<body>' . $html . '</body>';
|
|
libxml_use_internal_errors(true);
|
|
$doc = new DOMDocument();
|
|
$doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_SCHEMA_CREATE);
|
|
$xPath = new DOMXPath($doc);
|
|
|
|
// Apply to scripts
|
|
$scriptElems = $xPath->query('//script');
|
|
static::addNonceAttributes($scriptElems, static::$placeholder);
|
|
|
|
// Apply to styles
|
|
$styleElems = $xPath->query('//style');
|
|
static::addNonceAttributes($styleElems, static::$placeholder);
|
|
|
|
$returnHtml = '';
|
|
$topElems = $doc->documentElement->childNodes->item(0)->childNodes;
|
|
foreach ($topElems as $child) {
|
|
$content = $doc->saveHTML($child);
|
|
$returnHtml .= $content;
|
|
}
|
|
|
|
return $returnHtml;
|
|
}
|
|
|
|
/**
|
|
* Apply the give nonce value to the given prepared HTML.
|
|
*/
|
|
public static function apply(string $html, string $nonce): string
|
|
{
|
|
return str_replace(static::$placeholder, $nonce, $html);
|
|
}
|
|
|
|
protected static function addNonceAttributes(DOMNodeList $nodes, string $attrValue): void
|
|
{
|
|
/** @var DOMElement $node */
|
|
foreach ($nodes as $node) {
|
|
$node->setAttribute('nonce', $attrValue);
|
|
}
|
|
}
|
|
|
|
}
|