Разработка

Аудит безопасности и зачистка, чтобы не оставить после себя уязвимостей или “мусора”.

Аудит безопасности и зачистка, чтобы не оставить после себя уязвимостей или “мусора”.

Давайте разберем все по пунктам.

** Краткий вывод: ** Ваше ** финальное решение ** (с JavaScript, который собирает select из уже выведенных элементов) ** является безопасным и устойчивым ** . Но файлы, оставшиеся от наших ** промежуточных попыток ** , могут представлять определенный риск, и их обязательно нужно удалить.


  1. Анализ безопасности (по векторам атак)

Cross-Site Scripting (XSS) — Межсайтовый скриптинг

Это основная угроза для подобных кастомизаций. Атака происходит, когда злоумышленник внедряет в страницу вредоносный JavaScript-код, который выполняется в браузере другого пользователя.

  **
    Наш финальный код:
  **





  <li>
    Мы берем имя бренда и его URL из
    `
      data-атрибутов
    `
    :
    `
      data-brand-name
    `
    и
    `
      data-brand-url
    `
    .


  -
    Имя бренда вставляется в
    `
      data-brand-name
    `
    с помощью функции
    **
      `
        htmlspecialchars($arItem['NAME'])
      `
    **
    . Это ключевой момент безопасности! Эта функция превращает любые спецсимволы (вроде
    `
      <
    `
    `
      >
    `
    `
      "
    `
    `
      '
    `
    ) в безобидный текст. Даже если контент-менеджер назовет бренд
    `
      alert('xss')
    `
    , на страницу выведется просто текст, а не исполняемый скрипт.
    **
      Это безопасно.
    **


  -
    URL бренда (
    `
      $arItem['DETAIL_PAGE_URL']
    `
    ) генерируется самим Битриксом. Он считается безопасным. Теоретически, если контент-менеджер вручную впишет в какое-то поле
    `
      javascript:alert(1)
    `
    , это может сработать, но это уже проблема не шаблона, а политики управления контентом.


  -
    JavaScript вставляет данные в
    `
      select
    `
    через
    `
      selectHTML += \
    `
    ${name} `. Это считается безопасной практикой, так как переменные
    `
      name
    `
    и
    `
      url
    `
    уже “очищены” на стороне PHP.
-
  **
    Промежуточный код (который мы размещали в
    `
      elements.php
    `
    ):
  **





  <li>
    Там мы тоже использовали
    `
      htmlspecialchars
    `
    .
    **
      Это было безопасно.
    **

** Вердикт: ** Угрозы XSS в финальном решении нет.

SQL Injection — SQL-инъекции

Это атака на базу данных. В нашем случае она невозможна.

  • ** Наш финальный код: ** Не делает никаких прямых запросов к БД. Он работает с тем, что уже прислал компонент. ** Угрозы нет. **

  • ** Промежуточный код (где мы использовали CIBlockElement::GetList ): ** Мы использовали стандартный API Битрикса. Этот API имеет встроенную защиту от SQL-инъекций. ** Угрозы не было. **

** Вердикт: ** Угрозы SQL-инъекций нет.

File Inclusion (LFI/RFI) — Включение файлов

Это атака, при которой злоумышленник заставляет сервер подключить и выполнить вредоносный файл.

  • ** Наш финальный код: ** Не содержит функций include или require с переменными путями. ** Угрозы нет. **

  • ** Код Аспро (который мы анализировали): ** Содержит конструкции вида @include_once('page_blocks/' . $sViewElementsTemplate . '.php'); . Это потенциально опасно, ** ЕСЛИ ** переменная $sViewElementsTemplate может контролироваться пользователем через URL. Но в решениях “Аспро” такие переменные обычно жестко определяются из параметров компонента, которые задает администратор. Для обычного пользователя эта угроза минимальна.

** Вердикт: ** В нашей кастомизации угрозы нет.


  1. Устойчивость и «лишние» файлы

Это самый важный пункт для вас сейчас. Неудаленные тестовые файлы — это не только мусор, но и потенциальная “дыра” в будущем.

Давайте проведем ревизию всего, что мы создавали.

  **
    Файл №1 (Главный подозреваемый):
  **





  <li>
    **
      Путь:
    **
    `
      /local/templates/aspro-lite/components/bitrix/news/brands_custom/page_blocks/with_group/elements.php
    `


  -
    **
      Что это:
    **
    Наша последняя неудачная попытка, где мы делали собственный
    `
      GetList
    `
    и выводили селект прямо перед вызовом компонента Аспро.


  -
    **
      Что с ним делать:
    **
    **
      ВОССТАНОВИТЬ ОРИГИНАЛЬНУЮ ВЕРСИЮ.
    **
    Это критически важно. Скопируйте оригинальный файл из
    `
      /bitrix/templates/aspro-lite/components/bitrix/news/brands/page_blocks/with_group/elements.php
    `
    и замените им наш измененный файл в папке
    `
      brands_custom
    `
    . Это уберет двойной вызов и вернет штатную логику Аспро.
-
  **
    Папка №2 (Ненужная “матрешка”):
  **





  <li>
    **
      Путь:
    **
    `
      /local/templates/aspro-lite/components/bitrix/news/brands_custom/
    `


  -
    **
      Что это:
    **
    Копия шаблона комплексного компонента, которую мы создали, чтобы изменить вызов
    `
      elements.php
    `
    .


  -
    **
      Что с ним делать:
    **
    После восстановления
    `
      elements.php
    `
    (пункт 1), нам нужно убедиться, что мы используем
    **
      наш финальный, правильный шаблон
    **
    (
    `
      brands-list-with-select
    `
    ). Поэтому эта папка и ее правки нам
    **
      больше не нужны
    **
    . Ее можно либо оставить (она безвредна после восстановления
    `
      elements.php
    `
    ), либо (чтобы было чисто) удалить, а в вызове компонента
    `
      bitrix:news
    `
    на странице вернуть оригинальный шаблон
    `
      "brands"
    `
    . Для чистоты я рекомендую
    **
      удалить
    **
    и вернуть все как было.
-
  **
    Папка №3 (Наш рабочий шаблон):
  **





  <li>
    **
      Путь:
    **
    `
      /local/templates/aspro-lite/components/bitrix/news.list/brands-list-with-select/
    `


  -
    **
      Что это:
    **
    Единственный файл, который нам действительно нужен. В его
    `
      template.php
    `
    лежит финальный, рабочий код с JS.


  -
    **
      Что с ним делать:
    **
    **
      ОСТАВИТЬ.
    **
    Это и есть результат нашей работы.

Рекомендации по «зачистке» и усилению (Ваш чек-лист)

  • ** Восстановите elements.php . ** Скопируйте оригинал из /bitrix/.../ в /local/.../brands_custom/... (как описано в пункте 1 выше).

  • ** Верните оригинальный шаблон комплексного компонента. ** На странице /contacts/otdel-prodazh/index.php в параметрах компонента bitrix:news верните ему его родной шаблон brands .

  • ** Удалите ненужную копию. ** Удалите папку /local/templates/aspro-lite/components/bitrix/news/brands_custom/ .

  • ** Проверьте финальную связку. ** Убедитесь, что оригинальный шаблон brands (а точнее, файл .../page_blocks/with_group/elements.php внутри него) вызывает компонент bitrix:news.list . Если вы его не меняли, то он вызывает news.list с шаблоном brands-list . ** Это нормально! **

  • ** Создайте финальную копию. ** Теперь, когда все чисто, скопируйте оригинальный шаблон .../components/bitrix/news.list/brands-list/ в .../local/.../components/bitrix/news.list/brands-list-with-select/ .

  • ** Вставьте финальный код. ** В template.php этого нового шаблона вставьте наш финальный код с JavaScript.

  • ** Примените шаблон. ** В параметрах компонента bitrix:news на странице укажите, чтобы он для списка новостей ( news.list ) использовал ваш шаблон brands-list-with-select . Этот параметр находится в самом низу настроек комплексного компонента.

Это может показаться сложным, но по сути мы “откатываем” все изменения, кроме самого последнего и самого правильного. Это гарантирует, что мы не оставили за собой никаких “хвостов”.

Вы проделали огромную работу, и финальный штрих — навести порядок. После этого ваша кастомизация будет и функциональной, и безопасной, и отказоустойчивой.