← Назад к заметкам

Заметки

Код статичного приложения можно посмотреть по URL обработчика

Почему в статичном приложении Bitrix24 нельзя хранить вебхуки, токены и закрытую бизнес-логику.

Статичное приложение — это обычный frontend. HTML и JavaScript загружаются в браузер, поэтому токены, вебхуки и закрытую логику в таком коде хранить нельзя.

Проблема

Если приложение сделано как статичное, его HTML и JavaScript доступны пользователю. Код можно посмотреть через DevTools, вкладку Network или напрямую по URL файлов.

Статичное приложение удобно для простого интерфейса: виджетов, вкладок, кнопок, таблиц и форм. Но всё, что попало в index.html, script.js или другой frontend-файл, нужно считать открытым.

Типовая ошибка:

  • создали статичное приложение;
  • добавили в JavaScript входящий вебхук или постоянный токен;
  • приложение открылось внутри Bitrix24;
  • пользователь открыл DevTools;
  • секретный URL оказался виден вместе с кодом приложения.

Если значение нельзя показывать пользователю, его не должно быть в статичном JavaScript.

Что нельзя хранить в статике

Всё, что попало во frontend-код, можно прочитать. Даже если это не выводится на страницу.

В статичном приложении нельзя хранить постоянные ключи доступа:

  • входящие вебхуки Bitrix24;
  • OAuth-токены;
  • секреты приложений;
  • пароли от внешних сервисов;
  • ключи API;
  • служебные URL для административных действий.

Даже если переменная не используется напрямую в интерфейсе, она всё равно остаётся в коде, который загружает браузер.

// Так делать нельзя.

const WEBHOOK_URL = 'https://example.bitrix24.ru/rest/1/example_key/crm.deal.list.json';

fetch(WEBHOOK_URL, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        select: ['ID', 'TITLE'],
    }),
})
    .then(function (response) {
        return response.json();
    })
    .then(function (data) {
        console.log(data);
    });

Такой вебхук можно скопировать из исходников и использовать отдельно от приложения.

Во frontend-коде не стоит хранить правила, которые пользователь не должен видеть.

  • закрытые коэффициенты и формулы расчёта;
  • скрытые условия маршрутизации заявок;
  • списки внутренних исключений;
  • служебные ID пользователей, отделов или клиентов;
  • алгоритмы, которые должны выполняться только на сервере.

Если правило влияет на доступ, деньги, маршрутизацию или закрытую бизнес-логику, лучше держать его на сервере.

Как делать безопаснее

Статичное приложение можно оставить для интерфейса, а секреты и важную логику вынести в серверный обработчик.

В статичном приложении нормально держать:

  • разметку интерфейса;
  • отрисовку таблиц, кнопок и форм;
  • вызовы BX24.callMethod в рамках прав текущего пользователя;
  • простую валидацию формы для удобства;
  • код, который не содержит секретов.

Если приложение работает через JS SDK Bitrix24, оно действует в рамках пользователя, который открыл приложение. Для простых интерфейсных задач этого часто достаточно.

Серверный обработчик для секретов

Если нужны постоянные токены, закрытая логика или доступ к внешним сервисам, нужен backend-обработчик.

В таком варианте 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);
            });
    }
);

Важный момент: данные из frontend нельзя считать доверенными. Даже user_id из примера сервер должен проверить сам, а не просто принять как истину.

Секреты при этом хранятся и используются только на сервере. В JavaScript остаётся только вызов своего обработчика.