Як реалізувати захищені заголовки за допомогою Cloudflare Workers?

Покроковий посібник із впровадження безпечних HTTP-заголовків на веб-сайтах, які працюють на Cloudflare за допомогою Cloudflare Workers.

Існує багато способів застосувати заголовки відповідей HTTP, щоб захистити сайти від поширених уразливостей, таких як XSS, Clickjacking, MIMI-сніфінг, міжсайтове впровадження та багато іншого. Це широко прийнята практика і рекомендована OWASP.

Раніше я писав про реалізацію заголовків у веб-сервері, як-от Apache, Nginx та IIS. Однак, якщо ви використовуєте Cloudflare для захисту та перезарядки своїх сайтів, ви можете скористатися цим Працівники Cloudflare для маніпулювання заголовками відповідей HTTP.

Cloudflare Workers — це безсерверна платформа, де можна запускати код JavaScript, C, C++, Rust. Його розгортають у кожному центрі обробки даних Cloudflare, а їх понад 200 у всьому світі.

Реалізація є дуже простою та гнучкою. Це дає вам можливість застосовувати заголовки до всього сайту, включаючи субдомен або певний URI з відповідна скоромовкаn за допомогою 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-Policy – ​​якщо вам потрібно застосувати свою політику програми, ви можете зробити це тут.

Наприклад, якщо вам потрібно отримати вміст через iFrame за кількома URL-адресами, ви можете скористатися перевагами предків кадрів, як показано нижче.

"Content-Security-Policy" : "frame-ancestors 'self' gf.dev techukraine.net.com",

Вищезазначене дозволить завантажувати вміст із gf.dev, techukraine.net.com і власного сайту.

  Як вимкнути дисплей 90 Гц на Google Pixel 4 і Pixel 4 XL

X-Frame-Options – ви можете змінити на SAMEORIGIN, якщо ви маєте намір відображати вміст свого сайту на деякій сторінці в межах того самого сайту за допомогою iframe.

"X-Frame-Options": "SAMEORIGIN",

Сервер – тут можна очистити заголовок сервера. Поставте все, що вам подобається.

"Server" : "techukraine.net Server",

RemoveHeaders – чи потрібно видалити деякі заголовки, щоб приховати версії, щоб зменшити вразливість до витоку інформації?

Ви можете зробити це тут.

let removeHeaders = [
	"Public-Key-Pins",
	"X-Powered-By",
	"X-AspNet-Version",
]

Додавання нових заголовків – якщо вам потрібно передати спеціальні заголовки до ваших програм, ви можете додати їх у розділі securityHeaders, як показано нижче.

let securityHeaders = {
	"Content-Security-Policy" : "frame-ancestors 'self' gf.dev techukraine.net.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 і виберіть сайт.
  • Перейдіть на вкладку Workers >> Add route.
  • Введіть URL-адресу в Route; ви можете застосувати Regex тут.
  • Виберіть новостворених робітників і збережіть
  ODCF8005E – рівень P2P не зміг прив’язатися до порту UDP у WebSphere 8.5

Це все; протягом секунди ви помітите, що всі заголовки реалізовано на сайті.

Ось як це виглядає в Chrome Dev Tools. Ви також можете перевірити заголовок за допомогою інструмента заголовка HTTP.

Я не знаю, чому заголовок сервера не відображається. Я думаю, Cloudflare скасовує це.

Розумієте, загальна реалізація займає приблизно 15 хвилин, і не потрібні простої чи перезавантаження, як Apache або Nginx. Якщо ви плануєте застосувати це на робочому місці, я б запропонував спочатку протестувати на нижчому середовищі або за допомогою маршруту ви можете застосувати на тестових сторінках, щоб перевірити результати. Коли ви задоволені, штовхайте туди, куди хочете.

Це круто!

Завдяки Скотт для коду.