Перейти до змісту

Перевірка заголовків безпеки вашого сайту

Подивіться, які HTTP-заголовки безпеки надсилає ваш сайт і від чого кожен захищає. Ми читаємо відповідь головної сторінки й основних хостів, пояснюємо кожен заголовок простими словами і підказуємо, що змінити.

Що дивиться перевірка заголовків безпеки

Разом із кожною сторінкою сервер передає браузеру кілька вказівок: відкривай сайт лише по HTTPS, завантажуй скрипти тільки звідси, не дозволяй іншим сайтам вбудовувати цю сторінку. Це і є заголовки безпеки. Якщо якогось бракує, нічого не ламається і це не означає, що сайт зламали, але в браузера на один запобіжник менше, якщо щось інше піде не так: наприклад, на сторінку потрапить чужий скрипт або ворожий сайт вбудує вашу сторінку в рамку.

Перевірка відкриває головну так, як це робить браузер, проходить усі переадресації й читає остаточну відповідь. Те саме робить для основних хостів, які знаходить, наприклад www чи api. Ми надсилаємо звичайні GET-запити й ще один запит із чужим заголовком Origin, щоб перевірити CORS. У ваші форми нічого не надсилаємо.

Заголовок за заголовком: що позначаємо

Заголовок Добрий приклад Що позначаємо
HTTP на HTTPS http:// переводить на https:// Сайт відкривається по http:// без переходу на HTTPS
Strict-Transport-Security max-age=31536000 на www і на домені без www Заголовка немає; max-age менше 180 днів; HSTS лише на www, а домен без www переадресовує без нього
Content-Security-Policy script-src 'self' з nonce або хешами Заголовка немає; лише режим звіту; 'unsafe-inline' без nonce чи хешу; скрипти з будь-якого джерела (*, https:, data:); 'unsafe-eval'
X-Frame-Options або frame-ancestors SAMEORIGIN, DENY або frame-ancestors 'self' Немає жодного, або frame-ancestors дозволяє будь-який сайт
X-Content-Type-Options nosniff Заголовка немає
Set-Cookie на головній Secure, а для сесійних cookies ще HttpOnly і SameSite Немає Secure на HTTPS; SameSite=None без Secure; сесійна cookie без HttpOnly чи SameSite
Server, X-Powered-By, X-AspNet-Version, X-Generator Без номерів версій Точна версія, наприклад nginx/1.24.0
Access-Control-Allow-Origin Немає, або лише ваші власні адреси * (гірше разом із credentials) або чужа адреса, повернута назад

Що ще перевіряємо в тих самих відповідях

  • /.well-known/security.txt: немає, прострочений чи некоректний, тож людина, яка знайшла проблему, не знає, куди про неї написати.
  • Сторонні скрипти без перевірки цілісності (SRI) і ресурси по HTTP на HTTPS-сторінках (змішаний вміст).
  • Приватні IP-адреси або назви на кшталт staging чи internal у заголовках відповіді.
  • Відповіді, що ставлять сесійну cookie без private чи no-store у Cache-Control, тож спільний кеш може їх зберегти.
  • Неповний набір: частина сучасних заголовків безпеки є, а HSTS чи CSP бракує.
  • Чи передається головна сторінка стиснутою.

Як закрити типові прогалини

Більшість заголовків - це один рядок у вебсервері, панелі хостингу чи налаштуваннях CDN. Приклади для nginx:

  • add_header Strict-Transport-Security "max-age=31536000" always; на HTTPS-сервері, і для www, і для домену без www. includeSubDomains і preload додавайте лише тоді, коли всі піддомени працюють по HTTPS.
  • add_header X-Content-Type-Options "nosniff" always; і add_header X-Frame-Options "SAMEORIGIN" always;
  • server_tokens off; ховає версію nginx, а expose_php = Off у php.ini прибирає версію PHP із X-Powered-By.
  • Позначте сесійні cookies як Secure, HttpOnly і SameSite у налаштуваннях застосунку чи CMS.
  • CSP налаштовуйте останнім: почніть із Content-Security-Policy-Report-Only, щоб побачити, що зламається, а потім перейдіть на робочий заголовок. Політику в режимі звіту наша перевірка вважає такою, що ще не захищає.

Пастка nginx: за замовчуванням add_header усередині блоку location скасовує всі рядки add_header, успадковані з блоку server, тож на частині сторінок заголовки можуть зникнути. Після кожної зміни запускайте перевірку знову.

Чого ця перевірка не робить

  • Не оцінює окремо Referrer-Policy, Permissions-Policy і заголовки Cross-Origin: ми лише порівнюємо їх між хостами. OWASP радить задавати Referrer-Policy і Permissions-Policy явно, тож перевірте їх самостійно.
  • Не ставить окремої оцінки-літери за заголовки.
  • Читає головну сторінку кожного основного хоста, а не всі сторінки. Внутрішні сторінки, відповіді API та адмінка можуть мати інші заголовки.
  • Для CSP перевіряє, звідки дозволено вантажити скрипти. Не тестує, чи можливе впровадження коду і чи не ламає ваша політика сайт.
  • Бачить cookies, які сервер ставить у відповіді головної, але не ті, що ставить JavaScript чи що зʼявляються після входу.
  • Не вимагає X-XSS-Protection: OWASP радить не задавати його взагалі або ставити 0.
  • Приховані номери версій - це охайно, але ПЗ від цього не оновлюється. Для цього є перевірка застарілого ПЗ.

Запитання

Відсутній заголовок - це вразливість?

Ні, це відсутній шар захисту. Більшість знахідок щодо заголовків позначено як посилення захисту: їхній вплив залежить від іншої слабкості, якої перевірка заголовків не бачить.

Чому ви позначаєте HSTS коротший за 180 днів?

Це поріг нашої перевірки. Довше - краще: один рік (max-age=31536000) - мінімум для списку попереднього завантаження HSTS (preload), де ще потрібен includeSubDomains.

Моїй CSP потрібен unsafe-inline через аналітику. Що робити?

Винесіть вбудовані скрипти у файли або дозвольте їх через nonce чи хеш. Із 'strict-dynamic' і nonce браузери ігнорують 'unsafe-inline' і списки дозволених хостів, і наша перевірка таке налаштування приймає.

Чому результат відрізняється від іншого сканера заголовків?

Інструменти по-різному проходять переадресації, читають різні хости й мають різні пороги. Ми читаємо остаточну сторінку після переадресацій і окремо повідомляємо про домен без www, якщо він переадресовує без HSTS.

Джерела

  1. MDN: Strict-Transport-Security (англійською) developer.mozilla.org
  2. MDN: Content-Security-Policy script-src (англійською) developer.mozilla.org
  3. OWASP: шпаргалка з HTTP-заголовків безпеки (англійською) cheatsheetseries.owasp.org
  4. RFC 9116: security.txt rfc-editor.org
  5. nginx: add_header (англійською) nginx.org
  6. nginx: server_tokens (англійською) nginx.org

Перевірте заголовки безпеки свого сайту

Введіть адресу сайту. Звіт покаже кожен заголовок зі значенням, яке ми побачили, і що додати. Безкоштовно, без реєстрації, лише читання.

Перевіряйте лише свої сайти або ті, на які маєте дозвіл. Як працює наш сканер