Как защитить сайт с личными кабинетами от взлома: XSS, SQL-инъекции и ролевая модель

Время чтения - 6 мин.
Дата публикации 02.07.2026

«Мой сайт взломали» — фраза, от которой у владельца бизнеса холодеет внутри. Слиты пароли клиентов, украдены данные, испорчена репутация. Для малого бизнеса это часто означает закрытие. Хорошая новость: большинства атак можно избежать, если изначально заложить правильную архитектуру и следовать базовым правилам.

В Falcon Space безопасность встроена на уровне ядра, но и вы сами можете многое сделать. Расскажу, от чего мы защищаем и как усилить защиту.

Основные угрозы для сайта с личными кабинетами

Для веб-приложений с авторизацией и передачей данных самые частые атаки:

  • SQL-инъекции — злоумышленник вставляет SQL-код в поля ввода, чтобы получить доступ к базе данных.
  • XSS (межсайтовый скриптинг) — внедрение JavaScript-кода на страницы сайта, чтобы украсть сессии или данные.
  • Подбор паролей (brute force) — автоматический перебор паролей по словарю.
  • Подмена сессии — кража куки сессии и использование чужого аккаунта.
  • Несанкционированный доступ к данным — пользователь должен видеть только свои данные, но из-за ошибки видит чужие.

Разберём, как платформа защищает от каждой угрозы и что ещё можете сделать вы.

Защита от SQL-инъекций: хранимые процедуры спасают

Классический веб-сайт часто строит SQL-запросы склеиванием строк: SELECT * FROM users WHERE id = ' + userId + '. Если злоумышленник передаст userId = 1 OR 1=1; DROP TABLE users; --, он может уничтожить базу данных.

В Falcon Space мы не конструируем запросы динамически из пользовательского ввода. Вся ваша бизнес-логика — это хранимые процедуры, которые вызываются с параметрами. Параметры строго типизированы и не могут быть интерпретированы как SQL-код. Это практически исключает SQL-инъекции на уровне приложения.

Пример процедуры (безопасно):

CREATE PROCEDURE [app].[get_user_by_id]
    @user_id int
AS
BEGIN
    SELECT * FROM users WHERE user_id = @user_id;
END

Даже если передать в @user_id строку '1; DROP TABLE users', SQL Server выдаст ошибку преобразования типов и ничего страшного не произойдёт.

Ваша задача: никогда не использовать динамическое выполнение SQL (sp_executesql с конкатенацией) внутри своих процедур. Пишите только параметризованные запросы.

Защита от XSS: экранирование вывода

XSS возникает, когда сайт выводит данные, введённые пользователем, без экранирования. Например, пользователь в поле «Имя» написал <script>alert('XSS')</script>, и этот код выполняется на страницах других пользователей.

В Falcon Space все данные, выводимые через стандартные компоненты (таблицы, формы), автоматически экранируются — теги превращаются в &lt; и &gt;. Но если вы выводите данные через свой HTML-код (например, в кастомном лендинге), то должны экранировать сами.

Для этого используйте функцию HtmlEncode в SQL-процедурах (платформа предоставляет такую возможность через внешнее действие или встроенные функции). Или, ещё проще, не позволяйте пользователям вводить HTML-теги вообще — добавьте валидацию.

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

Ролевая модель: кто что видит

Одна из самых частых уязвимостей — пользователь с ролью «Клиент» может, подменив ID в URL, посмотреть данные другого клиента (например, /order/123 вместо /order/456).

В Falcon Space мы защищаемся двумя способами:

  1. На уровне страниц — каждой странице назначаются роли, которые имеют к ней доступ. Если пользователь не входит в эти роли, он увидит ошибку 403.
  2. На уровне данных — в SQL-процедурах вы всегда должны передавать @username текущего пользователя и фильтровать данные по нему. Например:
CREATE PROCEDURE [app].[get_my_orders]
    @username nvarchar(100)
AS
BEGIN
    SELECT * FROM orders WHERE customer_username = @username;
END

Таким образом, даже если злоумышленник догадается вызвать процедуру с чужим username, он не сможет (потому что @username подставляется системой автоматически из сессии, а не из запроса пользователя).

Важное правило: никогда не доверяйте параметрам, переданным с клиента, для идентификации пользователя. Всегда используйте внутренний @username.

Дополнительные меры, которые вы можете настроить сами

Платформа даёт инструменты, а вы их используйте:

  • Капча на форме входа — защита от перебора паролей. Можно встроить reCAPTCHA от Google или простую математическую капчу.
  • Ограничение попыток входа — после 5 неудачных попыток блокировать IP на 15 минут. Реализуется через таблицу failed_logins и SQL-процедуру.
  • HTTPS — обязательно! Данные, передаваемые по HTTP, могут быть перехвачены. Настройте SSL-сертификат на сервере (бесплатно от Let's Encrypt).
  • Хранение паролей — мы используем хеширование с солью (bcrypt), не храним пароли в открытом виде. Не отключайте эту опцию.
  • Логирование действий — включайте логирование для важных операций (изменение пароля, удаление заказа, перевод денег). В критической ситуации вы сможете восстановить, кто и что делал.
  • Регулярные бэкапы — настройте автоматическое резервное копирование базы данных на сервере (раз в день). При взломе вы откатитесь на чистую версию за 5 минут.

Кейс: как мы защитили площадку от утечки данных

В одном из проектов (сервис для загородных домов) мы обнаружили, что заказчик в одной из кастомных процедур забыл фильтр по @username. В результате любой зарегистрированный пользователь мог, подставив order_id, посмотреть детали чужих заказов (адрес, телефон, стоимость). Это была серьёзная дыра.

Мы быстро исправили — добавили в процедуру условие:

AND customer_username = @username

Заодно написали скрипт, который проверил все процедуры на наличие такой уязвимости. В итоге нашли ещё 3 места с похожей проблемой. После исправления провели нагрузочное тестирование — скорость не упала.

С тех пор мы включили в наш чек-лист при сдаче проекта: проверка всех процедур, возвращающих данные, на фильтрацию по пользователю. Вы тоже можете попросить сделать такую проверку.

Что не может сделать платформа (и это ваша зона ответственности)

Некоторые аспекты безопасности зависят от вас:

  • Надёжные пароли сотрудников — требуйте сложные пароли, не используйте «admin» и «123456».
  • Безопасность сервера — держите Windows Server обновлённым, закрывайте ненужные порты, используйте брандмауэр.
  • Безопасность баз данных — не давайте пользователям лишних прав (например, не давайте права на запись в системные таблицы). У нас есть отдельная статья по информационной безопасности сайта.
  • Обучение сотрудников — чтобы они не переходили по фишинговым ссылкам и не сообщали пароли третьим лицам.

Безопасность — это не тумблер «включить», а процесс. Но правильная архитектура решает 80% проблем. В Falcon Space она правильная.

Резюме:

  • Используйте хранимые процедуры — SQL-инъекции исключены.
  • Фильтруйте данные по @username — защита от чужих данных.
  • Включите HTTPS и капчу.
  • Регулярно делайте бэкапы и проверяйте процедуры на уязвимости.

Следуя этим правилам, вы будете защищены от 95% атак. А если сомневаетесь — напишите нам, проведём аудит безопасности вашего сайта.

Насколько полезной была статья?
Falcon Space, автор блога

Автор статьи - Руслан Раянов

Cоздатель платформы Falcon Space
Запрос расчета стоимости веб-проекта на базе Falcon Space
Если видео Youtube плохо грузится, то попробуйте найти видео в ВК видео на канале Falcon Space
Сайт использует Cookie, Яндекс Метрику. Используя сайт, вы соглашаетесь с правилами сайта. См. Правила конфиденциальности и Правила использования сайта OK