-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
keyboard_arrow_right keyboard_arrow_down
-
-
keyboard_arrow_right keyboard_arrow_down
-
-
-
keyboard_arrow_right keyboard_arrow_down
- YCLIENTS
- Маркетплейс интеграций
- Плагинизация
- Руководство по созданию Backend плагина
- Руководство по разработке и безопасности плагинов
Руководство по разработке и безопасности плагинов
Поддерживаемые языки программирования
YCLIENTS предоставляет инфраструктуру для разработки backend-плагинов на любом языке программирования, при условии, что плагин взаимодействует с внешним миром через стандартные протоколы (HTTP, Kafka и т. д.) и использует переменные окружения для конфигурации.
Плагины взаимодействуют с публичным API YCLIENTS — доступ к внутреннему коду не предоставляется. Вся бизнес-логика строится вокруг запросов к API.
Что предоставляет YCLIENTS:
- Docker-проект — контейнеризированное окружение для разработки, в котором можно реализовать любую логику на своем языке/фреймворке.
- Инфраструктурные / Переменные окружения (
.env
) — DSN для PostgreSQL, Redis, Kafka, API-URL и токены. - SDK (опционально) — для PHP, с готовыми интерфейсами и адаптерами под Symfony и Laravel.
Приоритетные и протестированные языки (с поддержкой и примерами):
- PHP (внутренняя команда использует Symfony)
- Python
- Node.js
- Go
Вы можете использовать любой другой язык, реализуя подключение к API, БД, кэшу и Kafka самостоятельно используя данные для подключения через ENV.
Локальная разработка и тестирование
Перед началом убедитесь, что на вашей машине установлены Docker, Docker Compose и Git.
Чтобы начать разработку плагина, ознакомьтесь с руководством по ссылке.
Общие требования к безопасности
Запрет выполнения произвольного кода
Почему опасно:
- Выполнение динамического кода позволяет атакующему внедрить и запустить произвольную логику на сервере.
- Через
eval
,exec
и аналоги можно получить полный контроль над окружением и данными.
Как решается:
- Исключить все динамические вызовы:
eval()
,exec()
,system()
,shell_exec()
,passthru()
. - Отдавать предпочтение встроенным функциям и библиотекам с жёсткими границами поведения.
- Запретить
require
илиinclude
внешних URL — только локальные файлы из контролируемых директорий.
Предотвращение утечек внутренней информации
Почему опасно:
- Стектрейсы и подробные сообщения об ошибках раскрывают детали реализации: пути, библиотеки, версии.
- Злоумышленник использует эту информацию для поиска и эксплуатации уязвимостей.
Как решается:
- В продакшене показывать только обобщённые сообщения об ошибках (500 Internal Server Error).
- Логировать детальные стектрейсы локально или в защищенном хранилище, недоступном из внешних запросов.
Работа с входящими данными
Валидация и санитизация
Почему опасно:
- Принятие «сырых» данных без проверки приводит к неправильной работе логики, инъекциям и краху сервиса.
- Непредвиденные типы и форматы поломают алгоритмы и откроют путь для атак.
Как решается:
- Использовать JSON Schema или аналог для каждого API: ошибки в формате должны приводить к отказу в обработке (400 Bad Request).
- Проверять поля, типы, длины строк, диапазоны чисел, формат дат.
Защита от JSON Bomb и Path Traversal
Почему опасно:
- JSON Bomb (глубоко вложенные или разветвленные структуры) способен исчерпать память и CPU.
- Path Traversal (
../
) позволяет читать или записывать файлы вне корневой директории.
Как решается:
- Устанавливать лимит глубины и общего размера JSON (например, max 1 MB и глубина 10).
- При работе с файловыми путями нормализовать путь и требовать, чтобы итоговый путь находился внутри разрешенного каталога.
Защита от SQL-инъекций
Почему опасно:
- Прямая вставка параметров в SQL открывает путь для манипуляции запросами: чтение, изменение, удаление данных.
- Сложные атакующие структуры могут привести к удаленному выполнению произвольных SQL-команд.
Как решается:
- Использовать подготовленные выражения (prepared statements) или ORM, который автоматически экранирует параметры.
- Явно задавать типы всех входных параметров (integer, string).
Управление токенами и конфиденциальными данными
Почему опасно:
- Утечка секретов (паролей, ключей) дает полный доступ к сервисам, базам данных и пользовательским данным.
- Логи без фильтрации могут случайно записать токен или пароль.
Как решается:
- Хранить секреты только в переменных окружения, не в коде и не в VCS.
- Наложить запрет на логирование переменных
ENV
, фильтровать конфиденциальные поля. - Реализовать ротацию токенов: автоматические скрипты замены и уведомления об истечении.
Безопасность HTTP-интерфейса
Почему опасно:
- Нешифрованный трафик (HTTP) подслушивается и изменяется.
- Открытые endpoint’ы без аутентификации становятся точкой входа для атак.
Как решается:
- Принудительно включать HTTPS и HSTS-заголовки.
- Защищать публичные API через:
- HTTP Basic Auth, JWT или OAuth2;
- фильтрацию IP по белому списку.
- Защита от CSRF:
- Добавить CSRF-токены в формы и AJAX-запросы;
- Проверять Origin/Referer заголовки.
- Ограничение размера тела запроса (
max_body_size
) не более 10 MB (или по требованиям).
Предотвращение XSS и RCE
Почему опасно:
- XSS позволяет вставить скрипты в страницы, украсть cookie, перехватить сессии пользователей.
- RCE через загруженные файлы дает полный контроль над сервером.
Как решается:
- Экранировать все пользовательские данные при генерации HTML (использовать шаблонизаторы с автоматической экранизацией).
- Запретить
innerHTML
без валидации; использоватьtextContent
. - Проверять MIME-типы и расширения файлов перед сохранением:
- Только заранее разрешенные форматы (PDF, JPEG, PNG и т. д.).
Защита от DoS-атак
Почему опасно:
- Запросы без ограничений могут исчерпать память, CPU или сетевой канал, приведя к отказу в обслуживании.
- Массовые или повторяющиеся задачи в очередях приводят к блокировке ресурсов.
Как решается:
- Устанавливать таймауты на все внешние вызовы (HTTP, БД, очереди), например
5s
. - Ограничивать:
- Размер сообщений в очереди (Kafka, RabbitMQ);
- Количество параллельных воркеров (worker pool);
- Частоту запросов через rate limiter (например, 100 запросов/минуту).
Аудит и логирование
Почему опасно:
- Отсутствие структурированных логов усложняет расследование инцидентов.
- Секреты или персональные данные в логах могут попасть в руки злоумышленников.
Как решается:
- Логи в формате JSONL (каждая запись — одна строка) с полями:
timestamp
;- уровень по RFC 5424 (debug, info, warning, error и т. д.);
event_name
;trace_id
при распределенной трассировке.
- Исключить из логов:
- токены, пароли, ключи;
- персональные данные без обоснования и маскировки.