浏览代码

If the bbcodes require inline styles, then add the style-src 'unsafe-inline' rule to the Content-Security-Policy header

Visman 2 年之前
父节点
当前提交
f85dd4743c
共有 3 个文件被更改,包括 58 次插入6 次删除
  1. 20 0
      app/Core/Parser.php
  2. 16 6
      app/Core/View.php
  3. 22 0
      app/Models/Page.php

+ 20 - 0
app/Core/Parser.php

@@ -144,4 +144,24 @@ class Parser extends Parserus
 
 
         return $this->getHtml();
         return $this->getHtml();
     }
     }
+
+    /**
+     * Флаг использования встроенных стилей
+     */
+    protected bool $flagInlneStyle = false;
+
+    /**
+     * Устанавливает/возвращает флаг использования встроенных стилей в ббкодах
+     * (обработчик ббкода должен вызвать этот метод со значением true)
+     */
+    public function inlineStyle(bool $flag = null): bool
+    {
+        $prev = $this->flagInlneStyle;
+
+        if (true === $flag) {
+            $this->flagInlneStyle = $flag;
+        }
+
+        return $prev;
+    }
 }
 }

+ 16 - 6
app/Core/View.php

@@ -67,13 +67,9 @@ EOD;
      */
      */
     public function rendering(Page $p): ?string
     public function rendering(Page $p): ?string
     {
     {
-        foreach ($p->httpHeaders as $catHeader) {
-            foreach ($catHeader as $header) {
-                \header($header[0], $header[1]);
-            }
-        }
-
         if (null === $p->nameTpl) {
         if (null === $p->nameTpl) {
+            $this->sendHttpHeaders($p);
+
             return null;
             return null;
         }
         }
 
 
@@ -93,6 +89,20 @@ EOD;
             $this->endBlock(true);
             $this->endBlock(true);
         }
         }
 
 
+        $this->sendHttpHeaders($p);
+
         return $this->block('content');
         return $this->block('content');
     }
     }
+
+    /**
+     * Отправляет HTTP заголовки
+     */
+    protected function sendHttpHeaders(Page $p): void
+    {
+        foreach ($p->httpHeaders as $catHeader) {
+            foreach ($catHeader as $header) {
+                \header($header[0], $header[1]);
+            }
+        }
+    }
 }
 }

+ 22 - 0
app/Models/Page.php

@@ -401,6 +401,14 @@ abstract class Page extends Model
     protected function gethttpHeaders(): array
     protected function gethttpHeaders(): array
     {
     {
         foreach ($this->c->HTTP_HEADERS[$this->hhsLevel] as $header => $value) {
         foreach ($this->c->HTTP_HEADERS[$this->hhsLevel] as $header => $value) {
+            if (
+                'Content-Security-Policy' === $header
+                && $this->c->isInit('Parser')
+                && $this->c->Parser->inlineStyle()
+            ) {
+                $value = $this->addUnsafeInline($value);
+            }
+
             $this->header($header, $value);
             $this->header($header, $value);
         }
         }
 
 
@@ -409,6 +417,20 @@ abstract class Page extends Model
         return $this->httpHeaders;
         return $this->httpHeaders;
     }
     }
 
 
+    /**
+     * Добавляет в заголовок (Content-Security-Policy) значение unsafe-inline для style-src
+     */
+    protected function addUnsafeInline(string $header): string
+    {
+        if (false === \strpos($header, 'style-src')) {
+            return $header . ';style-src \'self\' \'unsafe-inline\''; // ???? брать правила с default-src ?
+        } elseif (\preg_match('%style\-src[^;]+?unsafe\-inline%i', $header)) {
+            return $header;
+        } else {
+            return \str_replace('style-src', 'style-src \'unsafe-inline\'', $header);
+        }
+    }
+
     /**
     /**
      * Устанавливает HTTP статус страницы
      * Устанавливает HTTP статус страницы
      */
      */