Отчет о внедрении контент‑фильтрации

Отчет о внедрении контент‑фильтрации, Markdown и предпросмотра

Дата: 2025‑10‑07

Модуль: modules/ContentFilter

1. Резюме

  • Реализован безопасный конвейер обработки контента (HTML/Plain/Markdown) с серверной санитизацией и ограниченными inline‑стилями.
  • Добавлен Markdown‑профиль с Parsedown (если установлен), далее обязательная HTML‑санитизация.
  • Расширена БД: исходник (content_source), формат (content_format), итоговый HTML (content_html). Миграция и бэкфилл.
  • В формах создания/редактирования статей добавлен выбор формата и живой предпросмотр (кнопка + авто, дебаунс 400 мс).
  • Исправлены ошибки SQL (1064), ENUM truncate (1265), Class not found; добавлены фолбэки совместимости.арапрпа

2. Цели и задачи

  • Сохранение полезного HTML и отсечение опасных конструкций (XSS, event‑атрибуты, javascript:/data: и пр.).
  • Поддержка трех форматов ввода: HTML, Plain Text, Markdown.
  • Улучшение UX: выбор формата + live‑предпросмотр именно санитизированного результата.
  • Хранение исходника и результата для удобного редактирования и быстрой выдачи.

3. Архитектура и компоненты

  • modules/ContentFilter/src/Models/FilterConfig.php

    • Профили: PROFILE_RICH, PROFILE_PLAIN, PROFILE_MD.
    • Белый список тегов/атрибутов; разрешение style у избранных тегов (дальше чистит CssSanitizer).
    • Разрешенные протоколы: http/https/mailto; запрет javascript:/data:.
  • modules/ContentFilter/src/Services/CssSanitizer.php

    • Свойства: color, background-color, text-align, text-decoration, font-weight, font-style, font-size, line-height.
    • Валидация значений: цвета (hex/rgb/rgba/имена), перечисления, длины (px/em/rem/%). Запрет url()/expression()/behavior/-moz-binding.
  • modules/ContentFilter/src/Services/HtmlSanitizer.php

    • sanitize(): по профилю (plain → escape; md → markdownToHtml → sanitizeHtml; rich → sanitizeHtml).
    • sanitizeHtml(): DOMDocument, очистка тегов/атрибутов, rel для target, фильтр ссылок и изображений, размеры img.
    • markdownToHtml(): Parsedown при наличии (modules/ContentFilter/Vendor/Parsedown.php) либо легкий конвертер.
    • Автоподключение зависимостей через require_once (без Composer).
  • modules/ContentFilter/preview.php

    • POST input + format → JSON { ok, sanitized }.
    • Профили: html → rich, plain → plain, md → md.

4. Интеграция в статьи

  • articles/create.php

    • Select «Формат текста» (HTML/Plain/Markdown).
    • Валидация по исходному тексту ($content_raw_for_form), минимум 100 символов.
    • Санитизация по выбранному профилю; запись: content (санитизированный HTML), content_source, content_format, content_html.
    • Live‑предпросмотр: кнопка + авто (дебаунс 400 мс) через modules/ContentFilter/preview.php.
    • Fix SHOW COLUMNS LIKE (без плейсхолдера, $pdo->quote + query).
    • Фолбэк ENUM: если столбец content_format ещё без 'md', сохраняется 'html', но санитизация идёт по реальному выбору.
  • articles/edit.php

    • Добавлен «Формат текста» и предпросмотр (как в create.php).
    • Исходник для редактирования — content_source (если есть), иначе legacy content.
    • Фолбэк ENUM на случай не обновлённой схемы (md → html при записи).
  • articles/view.php

    • Выводит content_html (если есть), иначе content.

5. Миграция БД

  • database/migrations/20251007_add_content_fields_and_backfill.php
  • Добавляет: content_source MEDIUMTEXT, content_format ENUM('html','plain','md'), content_html MEDIUMTEXT.
  • При наличии столбца content_format без 'md' — ALTER … MODIFY до ('html','plain','md').
  • Бэкфилл пакетами по id‑окну (batch=500); профили выбираются по имеющемуся формату или по наличию тегов.
  • SHOW COLUMNS LIKE без плейсхолдера (через $pdo->quote), совместимо с MySQL.

6. Безопасность

  • Удаление on* атрибутов, блокировка javascript:/data: в href/src, запрет опасных CSS‑конструкций.
  • rel="noopener noreferrer nofollow" для ссылок с target.
  • Проверки img: допустимые протоколы/относительные пути, числовые width/height.
  • Жесткий whitelist тегов/атрибутов и CSS свойств/значений.

7. UX: предпросмотр

  • Кнопка «Предпросмотр» и авто‑обновление при вводе/смене формата (дебаунс 400 мс).
  • Предпросмотр совпадает с финальным сохраняемым HTML (после санитизации).

8. Markdown

  • Parsedown (если файл Vendor/Parsedown.php присутствует) — полноценный Markdown: заголовки, списки, цитаты, блоки кода, горизонтальные линии и пр.
  • Даже при Parsedown результат проходит HtmlSanitizer.

9. Тестирование

10. Обратная совместимость

11. Ограничения и roadmap

12. Производительность

13. Использование

14. Ключевые изменения по файлам

15. Как проверить Parsedown

В режиме «Markdown» введите:

# Заголовок
- элемент 1
- элемент 2
> цитата
---

А для блока кода используйте тройные бэктики:

```php
echo "hi";


В предпросмотре должны появиться: `h1`, `ul`/`li`, `blockquote`, `hr`, а код — в `pre`/`code`.

## 16. План отката

- Удалить modules/ContentFilter/Vendor/Parsedown.php — включится лёгкий конвертер.
- При необходимости скрыть селектор формата и зафиксировать HTML/Plain.
- Миграцию не откатывать: новые поля безопасны и полезны.

Готово к эксплуатации. Для расширения whitelist или интеграции в другие разделы используйте сервисы модуля ContentFilter.
Категории: IT и программирование, Здоровье, Маркетинг, Путешествия
Изображений в статье: 3
Отчет о внедрении контент‑фильтрации - Изображение 1Отчет о внедрении контент‑фильтрации - Изображение 2Отчет о внедрении контент‑фильтрации - Изображение 3

Комментарии (1)

Сортировать:
Admin Admin 1
12.11.2025 18:36
Тестовый комментарий