Правка гайдов

This commit is contained in:
NikitaKalitov
2026-07-27 09:50:04 +03:00
parent 88997a338b
commit 99d48f393a
2 changed files with 86 additions and 5 deletions
+6 -5
View File
@@ -41,8 +41,6 @@ class DiagramProperty
{
$inputName = htmlspecialcharsbx($strHTMLControlName['VALUE']);
$rawValue = $value['VALUE'] ?? '';
// JSON_HEX_* флаги обязательны — см. раздел 5.
$jsValue = json_encode($rawValue, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT);
// Вариант A — рекомендуемый, приложение лежит внутри дерева портала (см. раздел 7):
// appOrigin — это просто origin текущего запроса, appUrl — конкретный файл.
@@ -60,8 +58,11 @@ class DiagramProperty
style="width:100%;height:600px;border:1px solid #ccc"></iframe>
<script>
(function () {
// Читаем initialValue из самого input.value, а не встраиваем JSON в
// инлайн-скрипт — так не нужны JSON_HEX_* флаги вообще (см. раздел 5):
// htmlspecialcharsbx() выше уже достаточно экранирует значение
// HTML-атрибута, а браузер сам декодирует его обратно в текст.
var appOrigin = <?= json_encode($appOrigin) ?>;
var initialValue = <?= $jsValue ?>; // строка JSON или ""
var input = document.getElementById(<?= json_encode($inputName) ?>);
var frame = document.getElementById('diagram-frame-<?= $inputName ?>');
@@ -71,7 +72,7 @@ class DiagramProperty
if (event.data.type === 'diagram:ready') {
frame.contentWindow.postMessage(
{ type: 'diagram:init', payload: initialValue || null },
{ type: 'diagram:init', payload: input.value || null },
appOrigin // никогда '*', см. раздел 5
);
} else if (event.data.type === 'diagram:change') {
@@ -121,7 +122,7 @@ class DiagramProperty
## 5. Требования безопасности (обязательны, не опциональны)
- При встраивании `initialValue` в инлайн-скрипт — **обязательно** `JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT` (см. пример в разделе 3). Без этого — риск XSS через выход из `<script>`-тега при вредоносном содержимом свойства.
- Значение всегда попадает на страницу только через `value`-атрибут hidden input (`htmlspecialcharsbx($rawValue)`, см. раздел 3), не через встраивание в инлайн-скрипт — так JSON-содержимое никогда не оказывается внутри JS-исходника, и `JSON_HEX_*`-экранирование не требуется вообще. Мост читает `input.value` напрямую в JS. Если по каким-то причинам всё же понадобится встроить значение в инлайн-скрипт (например, отдельный `initialValue` вместо чтения из DOM) — тогда обязателен `JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT` при `json_encode`.
- `event.origin` проверяется **в обе стороны**: и в мосте (когда он слушает сообщения от iframe), и в приложении (уже реализовано во frontend).
- `targetOrigin` у любого `postMessage` — всегда конкретный домен (`appOrigin`), **никогда `'*'`**.
- `name` у hidden input должен **точно** совпадать с `$strHTMLControlName['VALUE']` — это единственная связь между кастомным рендером и штатным сохранением формы.