如何使用Cloudflare Workers实现安全头?

使用Cloudflare Workers在由Cloudflare驱动的网站上实现安全HTTP头的逐步指南。

有许多方法可以实现HTTP响应头以保护站点免受常见漏洞的影响,例如XSS攻击、点击劫持、MIMI嗅探、跨站点注入等等。这是一种被广泛采用的做法,并受到OWASP推荐。

之前,我写过关于Apache、Nginx和IIS等服务器的文章。然而,如果您正在使用Cloudflare来保护和加速您的站点,您可以利用Cloudflare Workers来操作HTTP响应头。

Cloudflare Workers是一个平台,您可以在上面运行JavaScript、C、C++、Rust代码。它部署在全球200多个Cloudflare数据中心中。

实施非常简单灵活。它使您可以灵活地应用头部到整个站点,包括子域名或特定URI,使用matching patterRegex

在这个演示中,我将使用Scott Helme的链接。

让我们开始吧……👨‍💻

  • 点击创建Worker

  • 从链接9中复制worker.js代码并粘贴到脚本编辑器中
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 – 如果您需要应用自定义策略,可以在这里进行设置。

例如 – 如果您需要通过多个URL在iFrame上获取内容,您可以使用以下设置。

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

以上设置将允许从gf.devyaoweibin.com和自己的站点加载内容。

X-Frame-Options – 如果您希望在同一站点的某个页面中使用iframe显示您的站点内容,可以将其更改为SAMEORIGIN。

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

Server – 您可以在这里清除服务器头部信息。放入您喜欢的任何内容。

"Server" : "Geekflare Server",

RemoveHeaders – 您需要删除某些头部以隐藏版本以减轻信息泄露漏洞吗?

您可以在这里进行操作。

让我们把这段英文翻译成简体中文:

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

添加新的头部 – 如果您需要将一些自定义头部传递给您的应用程序,您可以在securityHeaders部分中添加它们,如下所示。

let securityHeaders = {
    "Content-Security-Policy" : "frame-ancestors 'self' gf.dev yaoweibin.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选项卡>>添加路由。
  • 在路由中输入URL;您可以在此应用正则表达式。
  • 选择新创建的工作器并保存。

就这些;在一秒钟内,您将注意到所有的头部都已应用到该网站。

以下是从Chrome Dev Tools上的效果。您还可以通过HTTP header tool测试头部。

我不知道为什么Server头部没有反映出来。我猜测Cloudflare正在覆盖它。

您可以看到,整个实施过程只需要约15分钟,而不需要像Apache或Nginx那样的停机时间或重启。如果您计划将其应用到生产网站上,我建议您首先在较低的环境中进行测试,或者借助路由的帮助,您可以在测试页面上应用并验证结果。一旦满意,就可以推送到任何您想要的地方。

这太棒了!

感谢Scott提供的代码。

类似文章