]> BookStack Code Mirror - bookstack/blob - app/Util/HtmlNonceApplicator.php
Started application of CSP headers
[bookstack] / app / Util / HtmlNonceApplicator.php
1 <?php
2
3 namespace BookStack\Util;
4
5 use DOMDocument;
6 use DOMElement;
7 use DOMNodeList;
8 use DOMXPath;
9
10 class HtmlNonceApplicator
11 {
12     /**
13      * Apply the given nonce to all scripts and styles in the given html.
14      */
15     public static function apply(string $html, string $nonce): string
16     {
17         if (empty($html)) {
18             return $html;
19         }
20
21         $html = '<body>' . $html . '</body>';
22         libxml_use_internal_errors(true);
23         $doc = new DOMDocument();
24         $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
25         $xPath = new DOMXPath($doc);
26
27         // Apply to scripts
28         $scriptElems = $xPath->query('//script');
29         static::addNonceAttributes($scriptElems, $nonce);
30
31         // Apply to styles
32         $styleElems = $xPath->query('//style');
33         static::addNonceAttributes($styleElems, $nonce);
34
35         $returnHtml = '';
36         $topElems = $doc->documentElement->childNodes->item(0)->childNodes;
37         foreach ($topElems as $child) {
38             $returnHtml .= $doc->saveHTML($child);
39         }
40
41         return $returnHtml;
42     }
43
44     protected static function addNonceAttributes(DOMNodeList $nodes, string $nonce): void
45     {
46         /** @var DOMElement $node */
47         foreach ($nodes as $node) {
48             $node->setAttribute('nonce', $nonce);
49         }
50     }
51
52 }