Безопасность сайта: OWASP, HTTPS, обновления и пароли
Зачем:Сайты взламывают не по личной неприязни, а автоматически и пачками, цепляясь за устаревшие плагины, слабые пароли и забытые ключи. После урока вы знаете десять самых частых классов проблем из списка OWASP Top 10 простыми словами, настраиваете HTTPS и заголовки безопасности, заводите двухфакторный вход и составляете для своего проекта короткий план защиты.
30 минут
Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.
OWASP Top 10 — список самых распространённых классов уязвимостей веб-приложений. От массовых атак защищают HTTPS, обновления, пароли и второй фактор.
Кого взламывают
Первая мысль: «кому нужен мой маленький сайт?» Ответ: боту. Взломы сегодня почти всегда автоматические. Программы круглосуточно обходят адреса в интернете, стучатся в /wp-login.php, ищут файл .env, пробуют известную дыру известного плагина, и если находят, то берут то, что есть: размещают скрытую рекламу и ссылки на свои сайты, рассылают спам с вашего адреса, воруют заявки и пароли. Им всё равно, что за сайт; важно, что он открыт.
Отсюда практичный вывод. Вам не нужна оборона от спецслужб. Нужно закрыть то, что закрывается дёшево: обновления, пароли с вторым фактором, шифрование, ввод, ключи. Это скучно и работает. Остальное уже вопрос размеров проекта.
Этот урок про сайт целиком, а следующий про форму отдельно.
OWASP и его список из десяти
OWASP (Open Worldwide Application Security Project, раньше Open Web Application Security Project) это открытое некоммерческое сообщество, которое выпускает свободные материалы о безопасности приложений. Самое известное это OWASP Top 10: список десяти самых распространённых классов проблем, который обновляют раз в несколько лет. Последняя редакция вышла в 2025 году. Это не контрольный перечень, а ориентир: «вот где на практике чаще всего ломают».
Прочитаем все десять простыми словами, с тем, что делает автор небольшого сайта.
- A01 Нарушение контроля доступа (Broken Access Control). Человек получает то, что ему не положено: поменял номер в адресе
/request/105на106и увидел чужую заявку; открыл/admin, не войдя. Лечение: сервер проверяет права на каждый запрос, а не верит тому, что пришло. - A02 Ошибки настройки (Security Misconfiguration). Пароль по умолчанию, открытая панель управления, включённая отладка, нет заголовков безопасности, список файлов виден всем. Лечение: настроить и проверить, отключить лишнее.
- A03 Сбои в цепочке поставки программ (Software Supply Chain Failures). Сайт опирается на чужое: CMS, плагины, темы, библиотеки, сборочные инструменты. Если там дыра или кто-то подменил пакет, она у вас. Лечение: обновлять, не ставить лишнего, брать из надёжных источников.
- A04 Сбои криптографии (Cryptographic Failures). Нет HTTPS, пароли хранятся открытым текстом или слабым хешем, секреты лежат где попало. Лечение: HTTPS везде, пароли хешировать (об этом урок об аутентификации), секреты хранить отдельно.
- A05 Инъекция (Injection). Введённый человеком текст превращается в код или часть запроса. Если в запрос к базе вставить текст как есть, кавычка и фрагмент SQL позволят вытащить всю базу (SQL-инъекция). Если вывести чужой текст на страницу без экранирования, чужой скрипт выполнится у других посетителей (XSS, межсайтовый скриптинг). Лечение: запросы с параметрами, экранирование при выводе, проверка ввода.
- A06 Небезопасный замысел (Insecure Design). Ошибка не в коде, а в идее: сброс пароля по дате рождения, форма без ограничения частоты, у которой нельзя остановить спам. Лечение: думать о злоупотреблении до разработки.
- A07 Сбои аутентификации (Authentication Failures). Слабые пароли, нет второго фактора, нет защиты от перебора. Лечение: длинные уникальные пароли, второй фактор, ограничение попыток.
- A08 Сбои целостности программ и данных (Software or Data Integrity Failures). Код или данные меняются без проверки: подключили скрипт с чужого сервера без проверки подлинности, автообновление без проверки подписи. Лечение: проверять источник, закреплять версии, у подключаемых скриптов указывать контрольную сумму (Subresource Integrity).
- A09 Сбои журналирования и оповещений (Security Logging and Alerting Failures). Атаку не видно, потому что ошибки и странные входы никто не записывает и не читает. Лечение: журнал ошибок и входов и оповещение о необычном.
- A10 Неправильная обработка исключительных ситуаций (Mishandling of Exceptional Conditions). Ошибка показывает посетителю внутренности (путь к файлам, запрос к базе) или приводит к тому, что защита «отключается». Лечение: понятное сообщение человеку, подробности в журнал, а при сбое запрещать, а не разрешать.
Схема ниже показывает связь между этим списком и мерами. Включайте меры и смотрите, какие автоматические попытки остановлены.
Это обычные автоматические попытки, которые идут на любой сайт. Включайте меры и смотрите, что остановлено.
- Бот перебирает пароли к странице входа в админку
Прошло. Что это по OWASP: A07 Authentication Failures. - Скрипт пробует известную дыру устаревшего плагина
Прошло. Что это по OWASP: A03 Software Supply Chain Failures. - В поле «Комментарий» вставлен скрипт, чтобы выполниться у других посетителей
Прошло. Что это по OWASP: A05 Injection (XSS). - В поле формы введена кавычка и фрагмент SQL, чтобы вытащить базу
Прошло. Что это по OWASP: A05 Injection (SQL). - Чужой в открытой сети Wi-Fi читает, что отправляет форма
Прошло. Что это по OWASP: A04 Cryptographic Failures. - Ваш сайт показан невидимым слоем на чужой странице, чтобы подменить клик
Прошло. Что это по OWASP: A02 Security Misconfiguration. - Сканер ищет файл .env и ключи в публичном репозитории
Прошло. Что это по OWASP: A02 Security Misconfiguration. - В адресе /request/105 меняют номер на 106 и читают чужую заявку
Прошло. Что это по OWASP: A01 Broken Access Control. - Бот отправляет форму заявки тысячу раз с рекламой
Прошло. Что это по OWASP: A06 Insecure Design.
Остановлено 0 из 9. Пока ничего: сайт открыт всем, кто попробует.
Текстовая альтернатива: лента из попыток (перебор пароля, дыра в плагине, скрипт и SQL в форме, перехват в Wi-Fi, встраивание сайта в чужую страницу, поиск ключей, подмена номера в адресе, спам) и список мер. Каждая попытка останавливается хотя бы одной подходящей мерой: двухфактором или ограничением частоты, обновлением, проверкой ввода, HTTPS, заголовками, хранением секретов вне кода, проверкой прав.
Проверьте себя: что такое инъекция и как её предотвращают?
Введённый человеком текст попадает в код или запрос как часть команды. Предотвращают параметрами запросов (значение передаётся отдельно от текста запроса), экранированием при выводе на страницу и проверкой ввода на сервере.
Как выглядит инъекция
SQL-инъекция проще, чем кажется. Допустим, сайт ищет заявку по телефону так:
запрос = "SELECT * FROM requests WHERE phone = '" + phone + "'" Если человек введёт обычный номер, всё работает. Но если он введёт ' OR '1'='1, запрос станет «выбрать все заявки, где телефон равен пустоте или единица равна единице», то есть вернёт всю таблицу. Правильно передавать значение отдельно от текста запроса:
SELECT * FROM requests WHERE phone = $1 (значение передаётся отдельно) База сама знает, что $1 это значение, а не команда, и текст ввода никогда не станет частью запроса. Вы видели такие параметры в уроках про SQL. XSS устроен так же, только жертва другая: не база, а браузер соседнего посетителя. Современные шаблонизаторы (Svelte, например) экранируют вывод автоматически, пока вы не просите их вставить «сырой» HTML.
HTTPS и заголовки безопасности
Про сертификаты вы узнали в уроке о HTTPS и TLS и в уроке о сертификатах на практике. Здесь что к ним добавить.
- HTTPS везде. Весь сайт, все ресурсы (иначе браузер блокирует «смешанное содержимое»), и перенаправление с
http://наhttps://. - HSTS это заголовок
Strict-Transport-Security: max-age=31536000. Он говорит браузеру: в течение года ходи на этот сайт только по HTTPS, не вспоминая про http. Без него человек, набравший адрес безhttps, на мгновение идёт по открытому соединению, и его можно перехватить. Включайте, когда уверены, что весь сайт работает по HTTPS. - Content-Security-Policy (CSP) это список источников, откуда странице можно брать скрипты, стили, картинки, и куда она может отправлять формы. Скрипт, который попал в страницу через XSS, но пришёл не из разрешённого источника, браузер не выполнит. Надёжный минимум:
default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'. Подключаемые сервисы (счётчик, карта) добавляются в политику явно. Слова'unsafe-inline'и'unsafe-eval'почти полностью лишают политику смысла: избегайте их. - X-Content-Type-Options: nosniff это браузер не «угадывает» тип файла и не выполняет картинку как скрипт.
- Referrer-Policy: strict-origin-when-cross-origin это на чужие сайты уходит только имя вашего сайта, а не полный адрес страницы (в нём могут быть данные).
- frame-ancestors (в CSP) или старый X-Frame-Options не дают встроить ваш сайт в чужую страницу. Иначе возможен «кликджекинг»: невидимый слой с вашей кнопкой под чужой картинкой.
- Флаги cookie (вы знаете их из урока об аутентификации):
Secure(только по HTTPS),HttpOnly(недоступна скриптам),SameSite=Lax(не уходит с чужих сайтов).
Где эти заголовки задают. В настройках веб-сервера (nginx, Caddy), в файле _headers на Netlify и Cloudflare Pages (строка с путём /*, под ней заголовки с отступом) или в настройках платформы. Не на всех платформах это возможно: на GitHub Pages свои заголовки задать нельзя (часть политики можно передать через meta-тег, но не всю: frame-ancestors в meta не работает). Если без этого не обойтись, перед сайтом ставят прокси или CDN, который добавляет заголовки.
Проверяют результат бесплатной проверкой MDN HTTP Observatory: она открывает ваш сайт и выставляет оценку с перечнем того, что не настроено. Запишите оценку «до» и «после» и вернитесь к ней, когда подключите новую библиотеку: легко сломать то, что настроили.
Проверьте себя: почему в CSP не оставляют 'unsafe-inline'?
Оно разрешает выполнять скрипт, вписанный прямо в страницу, а именно так действует XSS: внедрённый скрипт оказывается внутри страницы. С ‘unsafe-inline’ политика почти не защищает.
Обновления
Больше всего сайтов ломают через устаревшее: версию CMS, плагин, тему, библиотеку. Дыры в них публикуют, а автоматические сканеры проверяют, у кого ещё не закрыто. Поэтому:
- Обновляйте регулярно, критические исправления сразу. Для WordPress и других CMS включите автоматические обновления безопасности. Для проекта на коде: отчёт
npm audit, GitHub Dependabot или аналоги. - Не ставьте лишнего. Каждый плагин это чужой код и ваша ответственность. Выключили и не пользуетесь, значит, удалить.
- Берите из надёжных источников, смотрите, когда плагин последний раз обновлялся и сколько людей им пользуются. Заброшенный плагин это дыра на отсрочке.
- Закрепляйте версии и проверяйте источники, когда подключаете скрипты с чужих серверов (это тот самый A03 и A08).
- Есть копия, и вы знаете, как её развернуть (урок про резервные копии в части про инфраструктуру): обновление иногда ломает сайт, и откат должен быть возможен.
Пароли и второй фактор
Самый частый путь внутрь: украденный или угаданный пароль. Что работает.
- Уникальный длинный пароль для каждого сайта, который помнит менеджер паролей (Bitwarden, KeePass и другие; встроенные менеджеры браузеров и систем тоже годятся). Если один сайт потеряет базу, остальные остаются закрыты.
- Длина важнее хитрости. Современные рекомендации (NIST SP 800-63B) советуют длинные пароли, разрешать вставку и менеджеры, проверять по спискам утёкших паролей и не менять пароль по расписанию без причины: частая смена рождает «Пароль1», «Пароль2».
- Второй фактор (2FA): кроме пароля нужно что-то ещё. Приложение-аутентификатор (коды, которые меняются каждые тридцать секунд), аппаратный ключ или пасскей (из урока об аутентификации) надёжнее, чем SMS (номер можно перехватить). Но SMS лучше, чем ничего.
- Защищайте цепочку. Первым защищайте почту владельца: через неё сбрасываются пароли остальных. Затем регистратора домена (кто владеет доменом, тот владеет сайтом), хостинг или сервис выкладки, репозиторий и админку сайта.
- Резервные коды второго фактора сохраните в надёжное место: потерянный телефон не должен стать потерянным сайтом.
- Пароли посетителей (если у вас есть вход) не храните сами: только хеш медленной функцией (argon2id, bcrypt), как в уроке об аутентификации. Лучше не создавать вход, если без него можно обойтись.
Проверить, не утёк ли ваш адрес почты в известных взломах, можно в сервисе Have I Been Pwned (источник справа): он показывает, в каких утечках встречался адрес.
Секреты
Ключ к платёжной системе, пароль к базе, токен приёмника: всё это секреты. Их главное правило: секрет не должен попасть в репозиторий. Для этого его кладут в переменные окружения сервера или платформы (так делают все сервисы выкладки) или в менеджер секретов, а локальный файл .env вписывают в .gitignore. Если секрет всё же попал в репозиторий, даже на минуту, считайте его скомпрометированным: отзовите и выпустите новый. Автоматические сканеры находят ключи в публичных репозиториях за секунды, и удаление файла не удаляет его из истории.
Если всё-таки взломали
Скажите себе заранее, что вы будете делать, пока не горит.
- Остановить ущерб: отключить сайт (страница-заглушка), закрыть вход в админку.
- Сменить доступы: пароли и ключи всех связанных аккаунтов, отозвать токены, закрыть чужие сессии.
- Восстановить из чистой копии и обновить всё, что было устаревшим. Просто «вычистить» взломанный сайт ненадёжно: вы не знаете, что осталось.
- Найти, как вошли, по журналам, иначе повторится.
- Оценить, утекли ли данные людей, и если да, то сообщить, кому положено по закону. Когда утечка касается персональных данных, у оператора есть обязанности и сроки; о них в уроке про 152-ФЗ.
Практика
Вы в эпохе 2022 года: сайт собирается автоматически и выкладывается на платформу. Составьте для своего проекта план защиты на одну страницу: файл заголовков, второй фактор для пяти аккаунтов, правило обновлений, место для секретов и заметку о форме главного действия.
Проверка читает текст: она убедится, что в заголовках есть HSTS, CSP с нужными правилами без 'unsafe-inline', nosniff и политика реферера, а в таблице названа защита аккаунтов. Она не может проверить, что вы и правда поставили второй фактор. Это сделаете вы: откройте настройки каждого аккаунта и включите его, а потом проверьте настоящий сайт в Observatory.
Что было не так раньше
В 2000-х «безопасность» часто значила один пароль на всё и отсутствие обновлений: сайты на самодельных скриптах не обновлялись годами. Формы собирали SQL-запрос склейкой строк, а пароли хранили открытым текстом, о чём потом узнавали из публикаций об утечках. Появились платформы и стандарты, а с ними привычки: HTTPS стал нормой (с бесплатными сертификатами), браузеры начали предупреждать о небезопасных сайтах, а списки OWASP стали общим языком. Но главный враг остался прежним: «потом обновлю» и «у меня нечего красть».
Практика
Готовлю вашу страницу…
Тест
Вопрос 1 из 6
Карточки
Эти карточки попадут в повторение, когда вы завершите урок.
Что такое OWASP Top 10?
Ответ
Список из десяти самых распространённых классов уязвимостей веб-приложений, который составляет сообщество OWASP. Это не полный перечень проверок, а ориентир: версия 2025 года начинается с нарушения контроля доступа.
Что нужно для защищённого соединения?
Ответ
HTTPS с действующим сертификатом, перенаправление с http, HSTS (браузер ходит только по https), у cookie флаги Secure, HttpOnly и SameSite.
Зачем CSP и какие правила обязательны?
Ответ
Ограничивает источники кода и адреса отправки форм. Базовый набор: default-src 'self', object-src 'none', base-uri 'self', frame-ancestors, form-action 'self'. Без 'unsafe-inline'.
Какие аккаунты защищают в первую очередь?
Ответ
Почту владельца (через неё сбрасываются остальные пароли), регистратора домена, хостинг, репозиторий и админку. На каждом: уникальный пароль из менеджера и второй фактор.
Где хранить ключи и пароли?
Ответ
В переменных окружения и менеджере секретов, не в коде и не в репозитории (.env в .gitignore). Если секрет попал в репозиторий, его отзывают и выпускают новый.
Источники
- OWASP Top 10:2025 CC BY-SA, по-английски
- OWASP Cheat Sheet Series CC BY-SA, по-английски
- Content Security Policy (MDN) CC BY-SA, по-английски
- MDN HTTP Observatory CC BY-SA, по-английски
- OWASP: Password Storage Cheat Sheet CC BY-SA, по-английски
- NIST SP 800-63B: Digital Identity Guidelines, Authentication общественное достояние, по-английски
- Web Almanac 2024: Security CC BY-SA, по-английски
- Двухфакторная аутентификация (Википедия) CC BY-SA, по-русски
Дальше
Теперь вы знаете: OWASP: основы безопасности сайта, гигиена сайта: HTTPS, обновления, пароли и двухфакторный вход, заголовки безопасности и HTTPS.