所有文章

网站安全标头:它们是什么,该要求配置什么

六个 HTTP 标头,告诉浏览器如何保护你网站上的人。每个的作用,如何检查你自己的,以及一份可直接发给开发者的需求说明。

Radek,ENSOMEDIA发布于 5 分钟阅读In EnglishPo polskuAuf DeutschEn españolEn françaisبالعربية

有人打开你的网站时,服务器会把页面本身,连同几行访客看不到的指令,一起发给他的浏览器。这些就是 HTTP 标头。其中一些告诉浏览器如何保护网站上的人,例如只通过加密连接访问,或者不要运行来自陌生地址的脚本。

标头不花钱,只需设置一次。即便如此,很多网站还是没有,因为服务器的默认配置往往不包含它们。如果某次安全检测告诉你,你的网站“缺少安全标头”,本文解释这是什么意思,并给出一段可直接发给开发者的文字。

如何查看你的网站发送了什么

最快的办法是在你自己的浏览器里。在 Chrome、Edge 或 Firefox 中打开你的网站,按 F12(Mac 上是 Cmd+Option+I)。会打开开发者工具面板。选择“网络”(Network)标签并刷新页面。列表顶部会有一项是你网站的地址。点击它,找到“响应标头”(Response Headers)部分。

面板其余的内容不用管。你只需要找下面介绍的这些名称。

第二种办法是用免费的标头检查工具,例如我们的安全标头检查(英文),或 Mozilla 在其 MDN 网站上运营的 HTTP Observatory。输入你的地址,就会得到一份带评分的标头列表。把评分当作提示,而不是结论。

Strict-Transport-Security:始终使用 HTTPS

这个标头简称 HSTS,告诉浏览器:在一段设定的时间内,只通过 HTTPS 连接这个域名。例如在公共 Wi-Fi 上,有人可能试图拦截第一次未加密的连接,它能保护访客。

Strict-Transport-Security: max-age=31536000; includeSubDomains

max-age 是以秒为单位的时间,这里是一年。问题就在这里:一旦浏览器记住了这个标头,遇到证书问题的访客就不能再点击跳过警告。includeSubDomains 涵盖所有子域名,所以如果 shop.yourdomain.com 或某个被遗忘的 test.yourdomain.com 没有可用的 HTTPS,它们就会打不开。

所以先用较短的时间,比如一天,等一切正常后再延长。不要不加考虑就加上 preload,因为它很难撤销。

Content-Security-Policy:可信来源清单

这是最强大的标头,也是唯一真能把你的网站弄坏的标头。CSP 是一份清单,列出你的页面可以从哪些地方加载脚本、样式、图片和字体。如果攻击者设法注入恶意脚本,例如通过有漏洞的表单,浏览器会拒绝运行来自清单之外地址的代码。

麻烦在于,典型的小企业网站依赖大量外部服务:Google Analytics 或 Tag Manager、Facebook 像素、聊天窗口、地图、网络字体、YouTube 视频、支付网关。漏掉清单上的任何一个,网站对应的部分就会失效。聊天窗口消失,或者客户无法付款。

因此 CSP 应该先从试运行模式开始,名称是 Content-Security-Policy-Report-Only。在这个模式下,浏览器不拦截任何东西,只报告它本来会拦截什么。开发者在一两周的正常访问中收集这些报告,补全清单,然后才把标头切换为强制模式。它大致像这样:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://www.googletagmanager.com; img-src 'self' data: https:

这只是示意。真实的清单取决于你的网站用了什么。在插件很多的网站上,完整的 CSP 可能很难设置。即便如此,部分策略也好过没有。

四个较短的标头

X-Content-Type-Options: nosniff 告诉浏览器信任服务器声明的文件类型,而不是自己猜。没有它,作为文本或图片上传的文件在某些情况下可能被当作脚本处理。只要服务器正确声明文件类型,它很少会造成问题。

X-Frame-Options: SAMEORIGIN 阻止其他网站把你的网站嵌在框架里显示。它防御点击劫持:有人把你的页面隐形地加载在他自己的页面下面,诱使访客点击他们看不见的东西,比如下单按钮。较新的等效做法是 CSP 里的 frame-ancestors 'self',两者可以同时设置。如果你的网站本来就要出现在别处的框架里,比如合作方网站上的预约日历,开发者需要把该合作方的地址加到 frame-ancestors 里。

Referrer-Policy: strict-origin-when-cross-origin 意味着有人从你的网站点击链接前往另一个网站时,对方只知道他来自哪个域名,不知道是哪个页面。当你的页面地址里含有私密内容(比如订单号)时,这很重要。现代浏览器默认已经这样做,但明确设置这个标头没有成本。

Permissions-Policy: camera=(), microphone=(), geolocation=() 声明你的网站不使用摄像头、麦克风或位置信息。这样即使是被注入的脚本,也无法向访客请求这些权限。如果你的网站有“查找最近门店”工具或视频咨询,开发者会保留你需要的功能。

可直接发给开发者的需求说明

你可以复制下面的文字,换成你自己的网址,原样发送。

请为 yourdomain.com 添加安全标头,
覆盖每个页面,包括后台和商店:

Strict-Transport-Security: max-age=86400; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy-Report-Only: 与我们实际使用的
  脚本和服务相匹配的策略

启用 includeSubDomains 之前,请先确认
每个子域名都能通过 HTTPS 正常访问。如果一周内
没有出问题,请把 max-age 提高到 31536000。

CSP 先用 Report-Only 模式运行一两周。
然后请把报告的违规清单发给我,
我们一起约定何时切换为强制模式。

另外请告诉我标头是在哪里设置的
(服务器配置、.htaccess、Cloudflare 还是某个插件)。

最后这一条要求很重要。标头可以同时在好几个地方设置,同一个标头有两份不同的设置,下次有改动时很容易造成混乱。上线之后,再检查一遍标头,并把最重要的部分点一遍:联系表单、购物车、支付、聊天、地图和登录后台。

标头解决不了什么

标头是第二道防线。它们修不好过期的插件,也修不好弱密码。它们的作用是在其他环节失守时限制损害。

也不要不惜代价地追求检查工具里的最高分。一个有五个简单标头、支付正常的网站,处境比一个 CSP 完美、却让客户无法下单的网站好得多。

最后一点:如果某个工具让你添加 X-XSS-Protection 标头,不要把它当作紧急事项。大多数现代浏览器会忽略它,目前的建议是干脆不设,或者设为 0。