Заметки
Код статичного приложения можно посмотреть по URL обработчика
Почему в статичных приложениях Bitrix24 нельзя хранить токены, вебхуки и закрытую бизнес-логику.
Статичное приложение — это HTML и JavaScript, которые загружаются в браузер пользователя. Такой код нельзя считать закрытым, даже если приложение открывается внутри интерфейса Bitrix24.
Суть проблемы
Если приложение сделано как статичное, его исходный HTML и JavaScript попадают в браузер. Пользователь может посмотреть этот код через инструменты разработчика или открыть доступные файлы напрямую по URL.
Коротко
Статичное приложение удобно для простого интерфейса, виджетов и быстрых локальных доработок.
Но всё, что лежит в его index.html, script.js и других frontend-файлах,
нужно считать видимым.
Типовая ошибка выглядит так:
- создаётся статичное приложение;
- в JavaScript добавляется входящий вебхук или постоянный токен;
- приложение работает в интерфейсе Bitrix24;
- кто-то открывает DevTools и видит исходный код;
- секретный URL или токен становится доступен вместе с кодом приложения.
Поэтому статичное приложение лучше воспринимать как обычный frontend. Оно может показывать интерфейс, но не должно хранить секреты.
Где встречается
Проблема чаще всего появляется в локальных приложениях и виджетах:
- в статичных локальных приложениях на HTML/JS;
- в обработчиках, подключённых через
placement.bind; - в виджетах CRM-карточки;
- в фоновых виджетах;
- в приложениях, которые вызывают REST напрямую из браузера;
- в тестовых приложениях, которые потом остались в работе.
Если обработчик — это обычный публично доступный HTML или JS-файл, его нельзя использовать как место для закрытой логики.
Что нельзя хранить в статике
Всё, что попало в frontend-код, нужно считать доступным для просмотра.
Токены и вебхуки
В статичном приложении нельзя хранить постоянные ключи доступа:
- входящие вебхуки;
- OAuth-токены;
- секреты приложений;
- пароли от внешних сервисов;
- ключи API;
- административные URL для служебных действий.
Даже если код не отображается на странице, он всё равно может быть виден в исходниках, во вкладке Network или в загруженных JavaScript-файлах.
// Так делать нельзя.
const WEBHOOK_URL = 'https://example.bitrix24.ru/rest/1/example_key/crm.deal.list.json';
BX24.callMethod(
'crm.deal.list',
{
select: ['ID', 'TITLE'],
},
function (result) {
console.log(result.data());
}
); Внутренняя логика
В frontend-коде также не стоит хранить логику, которую нельзя раскрывать пользователям.
- правила расчёта закрытых коэффициентов;
- скрытые условия маршрутизации заявок;
- списки внутренних исключений;
- служебные ID пользователей, отделов или клиентов;
- алгоритмы, которые должны выполняться только на сервере.
Если пользователь не должен видеть правило, оно не должно находиться в статичном JavaScript.
Как делать безопаснее
Статичное приложение лучше использовать только как интерфейс, а чувствительные действия выносить на сервер.
Статика только для интерфейса
В статичном приложении можно оставить:
- разметку интерфейса;
- отрисовку таблиц, кнопок и форм;
- вызовы
BX24.callMethodв рамках прав текущего пользователя; - валидацию формы для удобства пользователя;
- код, который не содержит секретов.
Если приложение работает через JS SDK Bitrix24, оно действует в рамках прав пользователя, который открыл приложение. Это удобный вариант для простых интерфейсных задач.
Серверный обработчик для секретов
Если нужны постоянные токены, закрытая логика или доступ к внешним сервисам, лучше делать серверный обработчик.
В таком варианте frontend отправляет на сервер только безопасные параметры, а сервер уже сам:
- проверяет права;
- использует закрытые токены;
- обращается к REST или внешнему API;
- выполняет бизнес-логику;
- возвращает в приложение только нужный результат.
BX24.callMethod(
'user.current',
{},
function (result) {
if (result.error()) {
console.error(result.error());
return;
}
const user = result.data();
fetch('https://example.com/local/app/ajax.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_id: user.ID,
action: 'load_data',
}),
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});
}
); В этом примере секреты не лежат в JavaScript. Они должны храниться и использоваться только на серверной стороне.