Перевірка заголовків безпеки вашого сайту
Подивіться, які 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.
Джерела
- MDN: Strict-Transport-Security (англійською) developer.mozilla.org
- MDN: Content-Security-Policy script-src (англійською) developer.mozilla.org
- OWASP: шпаргалка з HTTP-заголовків безпеки (англійською) cheatsheetseries.owasp.org
- RFC 9116: security.txt rfc-editor.org
- nginx: add_header (англійською) nginx.org
- nginx: server_tokens (англійською) nginx.org
Перевірте заголовки безпеки свого сайту
Введіть адресу сайту. Звіт покаже кожен заголовок зі значенням, яке ми побачили, і що додати. Безкоштовно, без реєстрації, лише читання.
Перевіряйте лише свої сайти або ті, на які маєте дозвіл. Як працює наш сканер