Пошаговое руководство по реализации безопасных HTTP-заголовков на веб-сайтах на базе Cloudflare с использованием Cloudflare Workers.
Существует множество способов реализации заголовков ответов HTTP для защиты сайтов от распространенных уязвимостей, таких как CSS, Clickjacking, MIMI sniffing, межсайтовые инъекции и т. д. Это широко распространенная практика, рекомендованная OVASP.
Ранее я уже писал о реализации заголовков на таких веб-серверах, как Apache, Ngink и IIS. Однако, если вы используете Cloudflare для защиты и резервного копирования своих веб-сайтов, вы можете использовать Cloudflare Workers для управления заголовками ответов HTTP.
Cloudflare Workers — это бессерверная платформа, на которой вы можете запускать код JavaScript, C, C++, Rust. Он развернут в каждом дата-центре Cloudflare, которых в мире более 200.
Реализация очень проста и гибка. Это дает вам возможность применять заголовки ко всему сайту, включая поддомен или определенный URI с соответствующим шаблоном, используя Regex.
Для этой демонстрации я буду использовать код Скотта Хелма.
Давайте начнем… ??
- Скопируйте код worker.js с GitHub и вставьте в редактор скриптов.
const securityHeaders = { "Content-Security-Policy": "upgrade-insecure-requests", "Strict-Transport-Security": "max-age=1000", "X-Xss-Protection": "1; mode=block", "X-Frame-Options": "DENY", "X-Content-Type-Options": "nosniff", "Referrer-Policy": "strict-origin-when-cross-origin" }, sanitiseHeaders = { Server: "" }, removeHeaders = [ "Public-Key-Pins", "X-Powered-By", "X-AspNet-Version" ]; async function addHeaders(req) { const response = await fetch(req), newHeaders = new Headers(response.headers), setHeaders = Object.assign({}, securityHeaders, sanitiseHeaders); if (newHeaders.has("Content-Type") && !newHeaders.get("Content-Type").includes("text/html")) { return new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders }); } Object.keys(setHeaders).forEach(name => newHeaders.set(name, setHeaders[name])); removeHeaders.forEach(name => newHeaders.delete(name)); return new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders }); } addEventListener("fetch", event => event.respondWith(addHeaders(event.request)));
Пока не сохраняйте; вы можете настроить следующие заголовки в соответствии с требованиями.
Content-Security-Policies — если вам нужно применить собственную политику приложений, вы можете сделать это здесь.
Например, если вам нужно получить контент через iFrame на несколько URL-адресов, вы можете воспользоваться преимуществами родительского фрейма, как показано ниже.
"Content-Security-Policy" : "frame-ancestors 'self' gf.dev techblog.co.rs.com",
Это позволит загружать контент с gf.dev, vdzvdz.com и собственного сайта.
X-Frame-Options — вы можете изменить на SAMEORIGIN, если вы собираетесь отображать содержимое вашего сайта на странице того же сайта с помощью iframe.
"X-Frame-Options": "SAMEORIGIN",
Сервер — здесь вы можете очистить заголовок сервера. Ставь что хочешь.
"Server" : "techblog.co.rs Server",
RemoveHeaders — вам нужно удалить некоторые заголовки, чтобы скрыть версии, чтобы уменьшить уязвимость к утечке информации?
Вы можете сделать это здесь.
let removeHeaders = [ "Public-Key-Pins", "X-Powered-By", "X-AspNet-Version", ]
Добавление новых заголовков. Если вам нужно передать некоторые пользовательские заголовки в ваши приложения, вы можете добавить их в раздел securitiHeaders, как показано ниже.
let securityHeaders = { "Content-Security-Policy" : "frame-ancestors 'self' gf.dev techblog.co.rs.com", "Strict-Transport-Security" : "max-age=1000", "X-Xss-Protection" : "1; mode=block", "X-Frame-Options" : "SAMEORIGIN", "X-Content-Type-Options" : "nosniff", "Referrer-Policy" : "strict-origin-when-cross-origin", "Custom-Header" : "Success", }
Когда вы закончите настройку всех необходимых заголовков, назовите работника и нажмите «Сохранить и применить».
Большой! рабочий готов, то нам нужно добавить это на сайт, где вы хотите применить заголовки. Я применю это к своей лаборатории.
- Перейдите на главную страницу/панель инструментов Cloudflare и выберите местоположение.
- Перейдите на вкладку Рабочие >> Добавить маршрут.
- Введите URL-адрес в Маршрут; вы можете применить Regex здесь.
- Выберите только что созданных воркеров и сохраните
Вот и все; уже через секунду вы заметите, что все заголовки реализованы на сайте.
Вот как это выглядит в Chrome Dev Tools. Вы также можете протестировать заголовок с помощью инструмента HTTP-заголовков.
Я не знаю, почему заголовок сервера не отображается. Думаю, Cloudflare преодолевает это.
Видите ли, вся реализация занимает ~15 минут и не требует простоев или перезапусков, как Apache или Ngink. Если вы планируете развернуть это в рабочей среде, я предлагаю вам сначала протестировать в среде низкого уровня или с помощью маршрута вы можете развернуть его на тестовых страницах, чтобы проверить результаты. Когда вы будете удовлетворены, нажмите куда хотите.
Отлично!
Спасибо Скотту за код.