HTTP安全响应头 – 完整指南

作者: xusx 分类: HTTP 发布时间: 2019-08-03 07:41

销售“安全记分卡”的公司正在崛起,并已开始成为企业销售的一个因素。我听过那些担心从评级不佳的供应商处采购的客户,并且至少有一个案例根据评级改变了购买决策。

我调查了这些评级公司如何计算公司安全分数,结果发现他们使用了HTTP安全响应头(标头)使用和IP信誉的组合。

IP信誉基于黑名单和垃圾邮件列表以及公共IP所有权数据。只要您的公司不发送垃圾邮件并且可以快速检测并阻止恶意软件感染,这些通常应该是干净的。 HTTP安全头使用的计算方式与Mozilla Observatory(https://observatory.mozilla.org/)的工作方式类似。

因此,对于大多数公司而言,他们的得分主要取决于面向公众的网站上设置的安全标头。

设置正确的标题可以快速完成(通常无需重大测试),可以提高网站安全性,现在可以帮助您赢得与安全意识的客户的交易。

我怀疑这种测试方法的价值以及这些公司所要求的过高的定价方案。我认为这与真正的产品安全性无关。然而,它肯定会增加花时间设置标题并使它们正确的重要性。

在本文中,我将介绍常用的评估标头,为每个标题推荐安全值,并提供示例标头设置。在本文的最后,我将包括常见应用程序和Web服务器的示例设置。

一、重要的安全响应报头

1、Content-Security-Policy(CSP)内容安全,策略

CSP用于通过指定允许加载哪些资源来防止跨站点脚本。在此列表中的所有项目中,这可能是最合适的创建和维护以及最容易发生风险的时间。在开发CSP期间,请务必仔细测试它 – 阻止站点以有效方式使用的内容源会破坏站点功能。

创建初稿的一个很好的工具是Mozilla实验室CSP浏览器扩展(https://addons.mozilla.org/en-US/firefox/addon/laboratory-by-mozilla/)。在浏览器中安装它,彻底浏览要为其创建CSP的站点,然后在您的站点上使用生成的CSP。理想情况下,还可以重构JavaScript,因此不会保留内联脚本,因此您可以删除“unsafe inline”指令。

CSP可能很复杂且令人困惑,因此如果您想要更深入的了解,请访问官方网站(https://content-security-policy.com/)。

一个好的启动CSP可能如下(这可能需要在真实站点上进行大量修改)。在您的网站包含的每个部分中添加域名。

# Default to only allow content from the current site
# 默认情况下,仅允许访问当前站点的内容
# Allow images from current site and imgur.com
# 允许访问当前站点和 imgur.com 的图片资源
# Don't allow objects such as Flash and Java
# 不允许访问 Flash、Java 等对象
# Only allow scripts from the current site
# 仅允许访问当前站点的脚本
# Only allow styles from the current site
# 仅允许访问当前站点的样式
# Only allow frames from the current site
# 仅允许嵌入当前站点的内嵌
# Restrict URL's in the tag to current site
# 将 <base> 标记中的 URL 限制在当前站点
# Allow forms to submit only to the current site
# 表单仅允许提交到当前站点
Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';

2、Strict-Transport-Security(HSTS)严格安全传输

此标头告诉浏览器该网站应仅通过HTTPS访问 – 始终在您的网站启用HTTPS时启用。 如果您使用子域,我还建议在任何使用的子域上强制执行此操作。

Strict-Transport-Security: max-age=3600
Strict-Transport-Security: max-age=3600; includeSubDomains
Strict-Transport-Security: max-age=3600; preload

(1)max-age=:设置在浏览器收到这个请求后的秒的时间内凡是访问这个域名下的请求都使用HTTPS请求。
(2)includeSubDomains:可选,如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
(3)preload:可选,简单来说就是谷歌维护了一个域名列表(https://hstspreload.org/),凡是注册在列表内的域名都会具有从 http 跳转到 https 的浏览器内部行为。虽然列表由谷歌在维护,但是所有其他浏览器也会尝试使用这个列表。可参考谷歌官方hsts文档 (https://www.chromium.org/hsts)。

译者注

3、X-Content-Type-Options

此标头确保浏览器遵守应用程序设置的MIME类型。 这有助于防止某些类型的跨站点脚本绕过。

它还可以减少意外的应用程序行为,因为浏览器可能会错误地“猜测”某种内容,例如当开发人员将页面标记为“HTML”但浏览器认为它看起来像JavaScript并尝试将其呈现为JavaScript时。 此标头将确保浏览器始终遵守服务器设置的MIME类型。

X-Content-Type-Options: nosniff

注意:nosniff 只应用于 “script” 和 “style” 两种类型。事实证明,将其应用于图片类型的文件会导致与现有的站点冲突(https://github.com/whatwg/fetch/issues/395)。

译者注

4、Cache-Control 缓存控制

这个比其他人有点棘手,因为您可能希望针对不同的内容类型使用不同的缓存策略。

任何包含敏感数据的页面(例如用户页面或客户结帐页面)都应设置为no-cache。 其中一个原因是阻止共享计算机上的某人按下后退按钮或浏览历史记录并能够查看个人信息。

但是,很少更改的页面(如静态资源(图像,CSS文件和JS文件))很适合缓存。 这可以在逐页的基础上完成,也可以在服务器配置上使用正则表达式完成。

# Don’t cache by default
# 默认情况不使用缓存
Header set Cache-Control no-cache
# Cache static assets for 1 day
# 静态资源设置成缓存1天
Header set Cache-Control "max-age=86400, public"

5、Expires 过期时间

这将设置缓存应该使当前请求到期的时间。 如果设置了Cache-Control max-age标头,则会被忽略,因此我们只设置它以防止天真的扫描程序在不考虑缓存控制的情况下对其进行测试。

出于安全考虑,我们假设浏览器不应该缓存任何内容,因此我们将其设置为始终评估为过去的日期。

Expires: 0

6、X-Frame-Options

此标头指示是否允许在iFrame中显示该站点。

如果恶意网站将您的网站置于iFrame中,则恶意网站可以通过运行一些JavaScript来执行点击攻击攻击,该JavaScript会捕获iFrame上的鼠标点击,然后代表用户与该网站进行交互(不一定点击它们的位置) 认为他们点击了!)。

除非您专门使用框架,否则应始终将其设置为拒绝,在这种情况下,应将其设置为同源。 如果您在设计中将Frames与其他网站一起使用,您也可以在此处列出其他域名。

还应注意,此标头已被CSP frame-ancestors指令取代。 我仍然建议现在设置这个以安抚工具,但将来它可能会逐步淘汰。

X-Frame-Options: deny

7、Access-Control-Allow-Origin 跨域

告诉浏览器哪些其他网站的前端JavaScript代码可能会对相关页面发出请求。 除非您需要设置此项,否则默认设置通常是正确的。

例如,如果SiteA提供了一些想要向siteB发出请求的JavaScript,那么siteB必须使用标头提供响应,并指定允许SiteA发出此请求。 如果需要设置多个源,请参阅MDN上的详细信息页面。

这可能有点令人困惑,所以我绘制了一个图表来说明这个头如何运作:

使用Access-Control-Allow-Origin的数据流
使用Access-Control-Allow-Origin的数据流
Access-Control-Allow-Origin: http://www.one.site.com

8、设置Cookie

确保您的cookie仅通过HTTPS(加密)发送,并且无法通过JavaScript访问。 如果您的站点也支持HTTPS,则只能发送HTTPS cookie。 您应该始终设置以下标志:

  • Secure
  • HttpOnly

Cookie定义示例:

Set-Cookie: cookie名称=cookie值; Domain=域名; Secure; HttpOnly

有关更多信息,请参阅有关cookie的Mozilla文档(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)。

9、X-XSS-Protection

此标头指示浏览器停止检测到的跨站点脚本攻击的执行。 设置风险通常较低,但在投入生产之前仍应进行测试。

X-XSS-Protection: 1; mode=block

(1)X-XSS-Protection:

0: 表示关闭浏览器的XSS防护机制;
1:删除检测到的恶意代码, 如果响应报文中没有看到X-XSS-Protection 字段,那么浏览器就认为X-XSS-Protection配置为1,这是浏览器的默认设置1。

(2)mode=block:如果检测到恶意代码,再不渲染恶意代码。

译者注

二、Web服务器示例配置

通常,最好在服务器配置中在站点范围内添加标头。 Cookie在这里是例外,因为它们通常在应用程序本身中定义。

在向网站添加任何标题之前,我建议先检查 Observatory 或手动查看标题以查看已设置的标题。 一些框架和服务器会自动为您设置其中一些,因此只能实现您需要或想要更改的那些。

1、Apache 配置

.htaccess文件配置示例:

## Content-Security-Policy 内容安全,策略
## CSP
Header set Content-Security-Policy: default-src ‘self’; img-src ‘self’ https://i.imgur.com; object-src ‘none’; script-src ‘self’; style-src ‘self’; frame-ancestors ‘self’; base-uri ‘self’; form-action ‘self’;

## General Security Headers
## 通用的安全标头
Header set X-XSS-Protection: 1; mode=block
Header set Access-Control-Allow-Origin: http://www.one.site.com
Header set X-Frame-Options: deny
Header set X-Content-Type-Options: nosniff
Header set Strict-Transport-Security: max-age=3600; includeSubDomains

## Caching rules
# Don’t cache by default
## 缓存策略
# 默认情况下不使用缓存
Header set Cache-Control no-cache
Header set Expires: 0

# Cache static assets for 1 day
# 设置静态资源缓存1天
<filesMatch ".(ico|css|js|gif|jpeg|jpg|png|svg|woff|ttf|eot)$">
    Header set Cache-Control "max-age=86400, public"
</filesMatch>

2、Nginx 配置

## CSP
add_header Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';

## General Security Headers
add_header X-XSS-Protection: 1; mode=block;
add_header Access-Control-Allow-Origin: http://www.one.site.com;
add_header X-Frame-Options: deny;
add_header X-Content-Type-Options: nosniff;
add_header Strict-Transport-Security: max-age=3600; includeSubDomains;

## Caching rules
# Don’t cache by default
add_header Cache-Control no-cache;
add_header Expires: 0;

# Cache static assets for 1 day
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
    try_files $uri @rewriteapp;
    add_header Cache-Control "max-age=86400, public";
}

三、应用程序级标头设置

如果您无权访问Web服务器,或者具有复杂的标头设置需求,则可能需要在应用程序本身中进行设置。 这通常可以通过整个站点的框架中间件来完成,并且可以基于每个响应进行一次性头设置。

为简洁起见,我在示例中只包含了一个标题。 以相同的方式添加通过此方法所需的所有内容。

1、Node and express

// 添加一个全局挂载路径

app.use(function(req, res, next) {
res.header('X-XSS-Protection', 1; mode=block);
next();
});

2、Java and Spring

我没有很多使用Spring的经验,但Baeldung对Spring中的标题设置有很好的指导(https://www.baeldung.com/spring-response-header)。

3、PHP

我不熟悉各种PHP框架。 寻找可以处理请求的中间件。 对于单个响应,它非常简单。

header("X-XSS-Protection: 1; mode=block");
// header('X-Frame-Options: deny');

4、Python / Django

Django包含可配置的安全中间件,可以为您处理所有这些设置。 先启用它们。

对于特定页面,您可以将响应视为字典。 Django有一种特殊的方法来处理缓存,如果尝试以这种方式设置缓存头,应该进行调查。

response = HttpResponse()
response["X-XSS-Protection"] = "1; mode=block"

大家还可参考 https://github.com/twitter/secure_headers

译者注

四、结论

设置响应报头(标头)相对快速而简单。 对于数据保护,跨站点脚本和点击顶升,您的站点安全性会相当显着增加。

您还可以确保您不会因为依赖此信息的公司安全评级而失去未来的商业交易。 这种做法似乎在增加,我希望它在未来几年继续在企业销售中发挥作用。

如果以上有所遗漏,你认为还应该包含其他的安全响应报头,请留言回复。

原文:https://nullsweep.com/http-security-headers-a-complete-guide/

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注