Безопасность сайта — это не галочка в настройках, а десяток мест, где посторонний может получить лишнее: вход в панель, оплата заказа, загрузка файла, форма обратной связи. Ниже — что закрыто по умолчанию, ещё до того, как вы об этом подумали.
- 2 рубежа на входе: пароль и код из приложения
- 0 чужих скриптов на странице посетителя
- 950+ автоматических проверок в каждой сборке
Вход в панель
Код из приложения
Обычный TOTP по международному стандарту — подойдёт любое приложение, включая российский Яндекс Ключ. Ничего не уходит наружу: код сверяется на вашем сервере, а картинка для привязки рисуется системой.
Коды восстановления
Потерянный телефон не означает потерю доступа. Каждый код одноразовый: использованный вычёркивается и второй раз не сработает.
Деньги
Самое дорогое, что может случиться с интернет-магазином, — не взлом сервера, а тихая покупка за рубль. Три места, где это обычно и происходит:
- Цену нельзя подделать. При оформлении система берёт из браузера только «что» и «сколько штук», а название, цену и наличие перечитывает из своей базы. Подменить сумму в инструментах разработчика не выйдет.
- Уведомлению об оплате не верят на слово. Адрес, куда стучится банк, открыт всему интернету — иначе банк до него не достучится. Поэтому система либо переспрашивает платёжную систему по её же идентификатору, либо проверяет подпись — и в обоих случаях сверяет сумму: подпись подтверждает отправителя, но не то, сколько заплатили.
- Незаконченный драйвер включить нельзя. Способ оплаты, которым ни разу не прошёл живой платёж, помечен в системе и не включается — ни через форму, ни правкой в базе. Неоплаченный заказ лучше бесплатного.
- Товар не продаётся дважды. При оформлении строка товара блокируется, поэтому двое покупателей не купят последний экземпляр одновременно.
Подпись уведомления сверяется по исходному телу запроса и посимвольно-постоянным сравнением. Звучит мелочью, но именно на этих двух мелочах чаще всего и держится дыра: пересобранный JSON даёт другую подпись, а обычное сравнение строк по времени ответа выдаёт угаданные символы.
Что попадает на сервер
Форма загрузки — самый простой способ занести на сервер чужой код. Поэтому список разрешённых типов файлов белый, а не чёрный: разрешено перечисленное, остальное отклоняется.
- Исполняемые файлы не принимаются и не выполняются, даже если оказались в папке загрузок.
- SVG запрещён намеренно: это не картинка, а документ, в который можно вложить скрипт.
- Тип проверяется не по названию файла, а по его содержимому.
Роботы и формы
Проверочный код — свой, а не чужая служба, которой вы отдаёте посетителей. Четыре вида на выбор: картинка, пример, вопрос и ползунок.
- Правильный ответ не попадает в разметку. Звучит очевидно, но именно так проходятся многие самодельные каптчи — ответ лежит в скрытом поле страницы.
- Код одноразовый и живёт десять минут: угаданный нельзя переиспользовать повторной отправкой формы.
- Две каптчи на одной странице не мешают друг другу — у каждой свой экземпляр.
Данные посетителей
- Ни один посторонний сервис не узнаёт о заходе. Шрифты, значки и скрипты лежат на вашем сервере — браузер посетителя никуда больше не обращается.
- Счётчик посещаемости и карта подключаются только с согласия посетителя, а не при открытии страницы.
- Заголовки безопасности (CSP, HSTS) выставляются самой системой: чужой скрипт не выполнится, даже если попадёт на страницу.
- Автономный режим. Один переключатель — и сервер вообще перестаёт выходить в интернет, что бы ни было прописано в настройках интеграций. Заслон стоит на самом сетевом клиенте, а не в двадцати местах по отдельности.
Содержимое
Текст, который редактор сохраняет в базу, проходит чистку по белому списку
тегов и атрибутов. Обработчики событий, теги со скриптами и ссылки вида
javascript: на страницу не попадут, даже если их намеренно
вставить в редактор или прислать через форму.
Мы не обещаем неуязвимости — её не бывает. Обещаем другое: здесь нет десятка чужих дополнений от разных авторов, каждое со своим сроком жизни. Всё, что перечислено выше, — часть системы, и обновляется вместе с ней.
Проверить самому
Исходный код открыт: каждое утверждение с этой страницы можно найти в репозитории — вместе с автотестом, который его сторожит.