Закрытие утечки данных при интеграции 1С:ERP с маркетплейсами

Коротко: Ритейлер обнаружил утечку клиентских данных через интеграцию 1С:ERP с маркетплейсами — API-токены хранились в открытом виде, а менеджеры видели чужие заказы. За 6 недель команда внедрила RLS (ограничение доступа на уровне записей), перенесла токены в защищённое хранилище, настроила аудит обращений к API и поставила весь код интеграции под Git. Результат — 0 инцидентов за полгода и прохождение аудита ИБ.
Что произошло: анатомия утечки
Сеть из 40 розничных магазинов и собственного интернет-магазина торговала на четырёх маркетплейсах. Учёт вёлся в задачи по 1С:ERP, обмен заказами и остатками шёл через самописную обработку, написанную подрядчиком два года назад. В один из дней служба поддержки получила жалобу: клиент пожаловался, что в его личном кабинете отобразились данные другого покупателя — ФИО, телефон, адрес доставки.
Расследование показало системную проблему. Интеграция была спроектирована без учёта требований информационной безопасности. Главные дыры выглядели так:
- API-токены маркетплейсов хранились в открытом виде в общих модулях и константах базы. Любой пользователь с правами на конфигуратор или внешние обработки мог их прочитать.
- Отсутствие RLS — все менеджеры видели всю базу заказов целиком, включая персональные данные клиентов из других регионов и каналов продаж.
- Код интеграции жил только в конфигурации, без версионирования. Никто не знал, кто и когда внёс изменения, откатиться было невозможно.
- Логирования обращений к API не было — невозможно было понять, какие данные и кому выгружались.
Утечка персональных данных — это не только репутационный удар, но и штрафы по 152-ФЗ. После ужесточения законодательства в 2024–2025 годах суммы оборотных штрафов измеряются миллионами рублей.
Почему интеграция стала уязвимой?
Корень проблемы — типичный для российского ритейла подход «лишь бы работало». Когда подключали первый маркетплейс, задача была одна: чтобы заказы падали в ERP, а остатки уходили обратно. О безопасности не думали — это была «техническая утилита для пары менеджеров».
Но бизнес рос. К одному маркетплейсу добавились ещё три, число менеджеров выросло с 3 до 25, а объём персональных данных клиентов — до сотен тысяч записей. То, что было приемлемо для маленькой команды, превратилось в критическую уязвимость.
Какие данные были под угрозой?
| Тип данных | Где хранились | Кто имел доступ |
|---|---|---|
| ФИО, телефоны, адреса клиентов | Справочник «Контрагенты», документы заказов | Все 25 менеджеров |
| API-токены маркетплейсов | Константы, общие модули | Все с правами конфигуратора |
| История заказов по регионам | Документы «Заказ клиента» | Все менеджеры независимо от региона |
Неделя 1–2: аудит и защита API-токенов
Первое, что сделали, — провели полный аудит того, где и как хранятся секреты. Поиск по конфигурации показал, что токены встречались в 7 местах: в константах, в коде общих модулей, в макетах и даже в комментариях.
Решение — перенести все токены в защищённое хранилище. В 1С:ERP для этого используется механизм БезопасноеХранилищеДанных, который шифрует значения и привязывает их к конкретному объекту метаданных.
// Сохранение токена маркетплейса в безопасное хранилище
// Вызывается один раз администратором при настройке
Процедура СохранитьТокенМаркетплейса(ИдентификаторМаркетплейса, Токен) Экспорт
УстановитьПривилегированныйРежим(Истина);
ДанныеТокена = Новый Структура;
ДанныеТокена.Вставить("Токен", Токен);
ДанныеТокена.Вставить("ДатаУстановки", ТекущаяДатаСеанса());
// Привязываем к владельцу — справочнику настроек обмена
Владелец = "ИнтеграцияМаркетплейсы_" + ИдентификаторМаркетплейса;
ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(Владелец, ДанныеТокена);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедурыЧтение токена выполнялось только из привилегированного кода обмена, причём пользователь, под которым работал регламентный обмен, не имел прав на интерактивное чтение хранилища:
// Получение токена для авторизации запроса к API
Функция ПолучитьТокенМаркетплейса(ИдентификаторМаркетплейса) Экспорт
УстановитьПривилегированныйРежим(Истина);
Владелец = "ИнтеграцияМаркетплейсы_" + ИдентификаторМаркетплейса;
ДанныеТокена = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Владелец);
УстановитьПривилегированныйРежим(Ложь);
Если ДанныеТокена = Неопределено Или НЕ ДанныеТокена.Свойство("Токен") Тогда
ВызватьИсключение "Токен для маркетплейса не настроен: " + ИдентификаторМаркетплейса;
КонецЕсли;
Возврат ДанныеТокена.Токен;
КонецФункцииСтарые токены отозвали в личных кабинетах маркетплейсов и сгенерировали новые — на случай, если за два года они уже куда-то утекли.
Неделя 3–4: настройка RLS (ограничение доступа на уровне записей)
Главная задача — сделать так, чтобы менеджер видел только заказы своего канала продаж и региона. В 1С для этого служит механизм RLS (Record Level Security) — ограничения доступа на уровне записей, настраиваемые в ролях через шаблоны ограничений.
Как работает RLS в 1С?
RLS дополняет обычные права ролей условием на уровне строк таблицы. Если у пользователя есть право «Чтение» на документ «Заказ клиента», но RLS-условие не выполняется для конкретной записи — он эту запись просто не увидит. Запрос к данным автоматически дополняется условием на стороне СУБД.
Сначала мы добавили в справочник пользователей (через регистр сведений) привязку менеджера к каналу продаж и складу. Затем создали шаблон ограничения доступа в роли:
#Область ШаблонОграниченияДоступа
// Шаблон RLS для документа "Заказ клиента"
// Менеджер видит только заказы своего канала продаж
#Параметры(КаналПродаж)
ГДЕ Документ.КаналПродаж В
(ВЫБРАТЬ
| НастройкиДоступа.КаналПродаж
|ИЗ
| РегистрСведений.НастройкиДоступаМенеджеров КАК НастройкиДоступа
|ГДЕ
| НастройкиДоступа.Пользователь = &ТекущийПользователь)
#КонецОбластиВ платформе 1С:ERP уже встроена подсистема «Управление доступом» из БСП (Библиотека стандартных подсистем), которая позволяет настраивать RLS декларативно — через группы доступа и профили. Мы использовали именно её, чтобы не дублировать логику и не ломать стандартное обновление.
// Проверка доступа менеджера к заказу перед выгрузкой на маркетплейс
Функция ДоступРазрешен(СсылкаНаЗаказ, Пользователь) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Заказы.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказКлиента КАК Заказы
|ГДЕ
| Заказы.Ссылка = &Ссылка
| И Заказы.КаналПродаж В
| (ВЫБРАТЬ
| Настройки.КаналПродаж
| ИЗ
| РегистрСведений.НастройкиДоступаМенеджеров КАК Настройки
| ГДЕ
| Настройки.Пользователь = &Пользователь)";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаЗаказ);
Запрос.УстановитьПараметр("Пользователь", Пользователь);
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункцииЧто дала настройка RLS?
- Менеджер канала «Маркетплейс А» больше не видит заказы канала «Розница».
- Региональные менеджеры работают только со своими регионами.
- Персональные данные клиентов изолированы по бизнес-направлениям.
- Даже при попытке прямого запроса через консоль отчётов пользователь не получит чужих данных.
Важный нюанс — RLS даёт нагрузку на СУБД, так как каждое условие добавляется в запросы. Мы провели нагрузочное тестирование и оптимизировали индексы регистра НастройкиДоступаМенеджеров, чтобы интерфейс не «тормозил».
Неделя 5: внедрение аудита обращений к API
Без логирования невозможно было понять масштаб прошлой утечки и предотвратить будущие. Мы создали регистр сведений для фиксации каждого обращения к внешнему API — кто, когда, какой объём данных и каких клиентов выгрузил.
// Запись события обмена в журнал аудита
Процедура ЗафиксироватьСобытиеОбмена(Маркетплейс, ТипОперации, КоличествоЗаписей, Результат) Экспорт
НаборЗаписей = РегистрыСведений.ЖурналАудитаОбмена.СоздатьНаборЗаписей();
Запись = НаборЗаписей.Добавить();
Запись.Период = ТекущаяДатаСеанса();
Запись.Маркетплейс = Маркетплейс;
Запись.Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
Запись.ТипОперации = ТипОперации;
Запись.КоличествоЗаписей = КоличествоЗаписей;
Запись.Результат = Результат;
Запись.IPАдрес = ПолучитьСетевойАдресКлиента();
НаборЗаписей.Записать(Ложь);
КонецПроцедуры
// Получение IP-адреса для журнала
Функция ПолучитьСетевойАдресКлиента()
Попытка
Соединение = ПолучитьСоединениеИнформационнойБазы();
Возврат Строка(Соединение.КомпьютерПользователя);
Исключение
Возврат "Не определён";
КонецПопытки;
КонецФункцииПоверх журнала аудита сделали отчёт на СКД, который раз в сутки уходил руководителю ИБ. Любая аномалия — например, выгрузка 5000 заказов в нерабочее время — подсвечивалась красным.
Аудит API — это не просто требование безопасности. Это инструмент, который помог найти и второй, ранее незамеченный, дефект: одна из обработок выгружала на маркетплейс полные данные клиента вместо обезличенного идентификатора.
Неделя 6: постановка кода интеграции под Git
Последний, но критически важный шаг — версионирование. Код интеграции жил только внутри конфигурации, и при любой правке невозможно было понять, что именно изменилось. Это и создавало почву для скрытых уязвимостей.
Мы использовали механизм выгрузки конфигурации в файлы (формат EDT или выгрузка через конфигуратор) и подключили Git. Теперь каждое изменение проходило через ревью.
Как организовали процесс?
- Создали репозиторий, куда выгрузили модули интеграции в формате исходников.
- Настроили ветки:
main(продакшн),develop(тестирование), feature-ветки под задачи. - Ввели обязательный code review: ни одна строка кода, работающая с токенами или персональными данными, не попадала в продакшн без проверки второго разработчика.
- Подключили pre-commit хук, который проверял код на наличие «зашитых» секретов (токенов, паролей) — чтобы история не повторилась.
// Пример выгрузки модуля интеграции для версионирования
// Выполняется через пакетный запуск конфигуратора
// 1cv8 DESIGNER /DumpConfigToFiles "C:\Repo\src" /ConfigurationRepositoryF
// В коде интеграции — никаких хардкод-секретов, только обращение к хранилищу
Процедура ВыполнитьОбменСМаркетплейсом(ИдентификаторМаркетплейса) Экспорт
// Токен берётся из защищённого хранилища, а не из кода
Токен = ИнтеграцияМаркетплейсыСервер.ПолучитьТокенМаркетплейса(ИдентификаторМаркетплейса);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// ... логика обмена ...
// Фиксируем событие в журнале аудита
ИнтеграцияМаркетплейсыСервер.ЗафиксироватьСобытиеОбмена(
ИдентификаторМаркетплейса, "ВыгрузкаЗаказов", 0, "Успешно");
КонецПроцедурыGit-контроль не только повысил безопасность, но и упростил поддержку. Когда команда подключала новый маркетплейс, разработчики видели всю историю изменений и могли быстро откатиться при сбое. Подобрать команду для таких задач можно через фриланс 1С или найти разработчика 1С на бирже.
Результаты проекта за 6 недель
По итогам шестинедельного спринта ритейлер получил измеримые результаты:
| Показатель | До | После |
|---|---|---|
| Инциденты с утечкой данных | 1 подтверждённый | 0 за полгода |
| API-токены в открытом виде | 7 мест | 0 |
| Менеджеры с доступом ко всем данным | 25 | 0 (RLS по каналам) |
| Логирование обращений к API | Отсутствует | 100% событий |
| Версионирование кода | Нет | Git + code review |
Компания успешно прошла внутренний аудит информационной безопасности и подготовилась к проверке Роскомнадзора по 152-ФЗ. Стоимость проекта оказалась в десятки раз меньше потенциальных оборотных штрафов.
Какие выводы можно сделать?
Безопасность интеграции 1С с внешними системами — это не разовая настройка, а процесс. Четыре кита защиты, проверенные этим кейсом:
- Секреты — в хранилище, а не в коде. Любой токен или пароль в исходниках — это бомба замедленного действия.
- RLS — по умолчанию. Принцип минимально необходимого доступа должен закладываться на старте проекта, а не пришиваться потом.
- Аудит — обязателен. Без логов вы не узнаете об утечке, пока не станет поздно.
- Git — это гигиена. Версионирование защищает от случайных и злонамеренных изменений.
Найдите специалиста для решения этой задачи на koderion.ru
Читайте также: внедрение и поддержка 1С:ERP