最全 HTTP 安全响应头设置指南

更新日期: 2019-07-22阅读: 3.2k标签: 安全

销售“安全记分卡”的公司正在崛起,并已开始成为企业销售的一个因素。我从客户那里了解到,他们对从评级低的供应商那里的采购很不放心,至少有案例表明,他们依据最初的评级改变了采购决策。

我调查了这些评级公司是如何计算公司安全性得分的,结果发现他们组合使用了 HTTP 安全报头和 IP 信誉。

IP 信誉基于的是黑名单和垃圾邮件列表,再加上公共 IP 所有权数据。只要你的公司没有垃圾邮件,并且能够快速检测和阻止恶意软件感染,那么通常这些软件应该就是干净的。HTTP 安全报头使用的计算方式与 Mozilla Observatory 的工作方式类似。

因此,对于大多数公司来说,在很大程度上,他们的得分取决于对外开放的网站上设置的安全响应报头。

设置正确的响应报头可以快速实现(通常不需要进行大量测试),并能提高网站的安全性,现在还可以帮助我们赢得具有安全意识的客户。

我对这种测试方法的价值以及这些公司提出的过高的定价方案持怀疑态度。我不认为它与真正的产品安全性有那么大的关联。然而,这无疑增加了设置响应报头并维护其正确性的重要性,值得为此投入时间。

在本文中,我将介绍常用的评估响应报头,及每个报头的推荐安全值,并给出一个响应报头设置的示例。在本文的最后,还将给出常见的应用程序和 Web 服务器的设置示例。


重要的安全响应报头

Content-Security-Policy(CSP)

CSP 通过指定允许加载哪些资源的形式,来防止跨站脚本注入。在本文所列的安全响应报头中,正确地设置和维护 CSP,可能是最耗时的,也是最容易出现风险的。在开发 CSP 的过程中,要谨慎充分地测试它——以“合法”的方式阻塞站点使用的内容源会破坏站点的功能。

创建 CSP 初稿的一个很好的工具是 Mozilla 实验室的 CSP 浏览器扩展 。在浏览器中安装此扩展程序,首先充分地浏览要为其设置 CSP 的站点,然后在站点中使用生成的 CSP。理想情况下,还可以重构 JavaScript,使其没有残留的任何内联脚本,从而使我们可以删除“unsafe inline”指令设置。

CSP 的指令设置可能比较复杂,也很混乱,因此,如果你想更深入的了解 CSP,请访问其 官方网站 。

一个好的 CSP 开始可能是如下这样的(在真正的站点上使用时,可能需要进行大量的修改)。在包含该站点的每个部分中都添加域名。

# 默认情况下,仅允许访问当前站点的内容
# 允许访问当前站点和 imgur.com 的图片资源
# 不允许访问 Flash、Java 等对象
# 仅允许访问当前站点的脚本
# 仅允许访问当前站点的样式
# 仅允许嵌入当前站点的内嵌
# 将 <base> 标记中的 URL 限制在当前站点
# 表单仅允许提交到当前站点
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';


Strict-Transport-Security(HSTS)

该响应报头告诉浏览器,只能通过 HTTPS 访问网站——如果网站启用过 HTTPS,它将会一直生效。如果使用子域名,还建议在任何使用过的子域名对此加以强制。

Strict-Transport-Security:max-age=3600; includeSubdomains


X-Content-Type-Options

该响应报头确保浏览器遵守应用程序设置的 MIME 类型。这有助于防止某些类型的跨站脚本注入攻击。

它还能减少浏览器“猜测”某些内容不正确时的意外应用程序行为,例如,当开发人员将某个页面标记为“html”,但浏览器认为它更像 JavaScript,并试图将其渲染为 JavaScript 时。该响应报头能确保浏览器始终遵守服务端设置的 MIME 类型。

X-Content-Type-Options: nosniff


Cache-Control(缓存控制)

这个响应报头比其他的要稍微复杂一些,因为我们可能需要根据内容类型的不同而使用不同的缓存策略。

任何具有敏感数据的页面,如用户页面或客户结算页面,都应该设置成无缓存。其中一个原因是,防止共享计算机上的某个人按回退按钮或浏览历史记录又能查看到个人信息。

但是,对于像静态资产(图像、css 文件和 JS 文件)等很少变更的页面,很适合使用缓存。既可以通过逐页设置的方式来实现,也可以通过在服务端配置使用正则表达式的方式来实现。

# 默认情况不使用缓存
HeadersetCache-Control no-cache

# 静态资产设置成缓存1天
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
HeadersetCache-Control "max-age=86400,public"
</filesMatch>


Expires(过期时间)

该响应报头能设置当前请求缓存的过期时间。如果设置了 Cache-Control 的 max-age 响应报头,它将会被忽略,因此,在不考虑使用 Cache-Control 而进行本地缓存测试时,才设置它。

为了安全起见,我们假定浏览器不应该缓存任何内容,因此,我们可以把过期时间设置为一个总表示过期的数值。

Expires:0


X-Frame-Options

该响应报头用来表明站点是否允许在 iFrame 中展示。

如果恶意站点将我们的网站嵌套在 iFrame 中,那么恶意站点就可以通过运行一些 JavaScript 来执行点击劫持攻击,这些 JavaScript 能够捕获 iFrame 上的鼠标点击事件,然后代表用户与该站点进行交互(不必单击需要单击它们的地方!)。

应该始终将它设置为 deny(拒绝),除非特别需要使用内嵌,在这种情况下,应将其设置为 same-origin(同源)。如果需要在页面中内嵌其他的站点,也可以在此处以白名单的形式列举其他的域名。

还应该注意的是,这个响应报头已经被 CSP 的 frame-ancestors 指令所取代。目前,我仍然建议设置该响应报头来兼容不同的工具,但将来它可能会被逐步淘汰。

X-Frame-Options: deny


Access-Control-Allow-Origin

通过该响应报头可以告诉浏览器,允许哪些其他站点的前端 JavaScript 代码对页面发出请求。除非需要设置此响应报头,否则通常默认值就是正确的设置。

例如,如果站点 A 使用了一些 JavaScript,该 JavaScript 想要向站点 B 发出请求,那么站点 B 必须使用指定了允许站点 A 发出此请求的报头来提供响应。如果需要设置多个源,请参见 MDN 上的详情介绍页面 。

这可能有点难以理解,因此,我画了一个图表来说明这个响应报头是如何工作的:


Aess-Control-Allow-Orig:hp:/www.o.site.com


Set-Cookie

确保 cookie 仅能通过 HTTPS(加密)传送,并且不能通过 JavaScript 访问。如果站点也支持 HTTPS(站点应该支持 HTTPS),那么就只能发送 HTTPS cookie。我们通常需要设置如下标志:

  • Secure

  • HttpOnly

一个定义 Cookie 的示例:

Set-Cookie: <cookie-name>=<cookie-value>;Domain=<domain-value>; Secure; HttpOnly

请参阅 Mozilla 文档 中的 cookies 部分以了解更多相关信息。


X-XSS-Protection

该响应报头用来指示浏览器停止执行跨站脚本攻击检测。一般来说,设置它的风险很低,但在投入生产前仍需要进行测试。

X-XSS-Protection: 1;mode=block


Web 服务器的配置示例

通常,最好在服务器配置中添加站点范围内的响应报头。在此,cookie 是一个例外,因为它们通常是在应用程序内定义的。

在将任何响应报头添加到站点之前,我建议首先检查 Observatory 或手动查看响应报头,以查看已经设置了哪些响应报头。有些框架和服务器会自动设置其中一些响应报头,因此,我们只需设置我们需要的或想要变更的响应报头即可。


Apache 配置

.htaccess 中的 Apache 设置示例:

<IfModule mod_headers.c>
## CSP
HeadersetContent-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';

## 通用的安全响应报头
HeadersetX-XSS-Protection:1; mode=block
HeadersetAccess-Control-Allow-Origin: http://www.one.site.com
HeadersetX-Frame-Options: deny
HeadersetX-Content-Type-Options: nosniff
HeadersetStrict-Transport-Security: max-age=3600; includeSubDomains

## 缓存策略
# 默认情况下不使用缓存
HeadersetCache-Control no-cache
Header set Expires:0

# 设置静态资产缓存1天
<filesMatch ".(ico|css|js|gif|jpeg|jpg|png|svg|woff|ttf|eot)$">
HeadersetCache-Control "max-age=86400,public"
</filesMatch>

</IfModule>


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';

## 通用的安全响应报头

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;

## 缓存策略

** 默认不使用缓存 **

add_header Cache-Control no-cache;
add_header Expires: 0;

** 设置静态资产缓存 1 天 **

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 服务器的权限,或者需要设置复杂的响应报头,那么我们就可能需要在应用程序内设置这些响应报头了。这通常可以在整个站点的框架中间件中实现,也可以在每次响应的基础上进行一次性的报头设置。

为了简便起见,在示例中,只包含了一个响应报头。所需的全部响应报头都是以相同的方式通过该方法来添加的。


Node 及 express:

添加一个全局挂载路径:

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


Java 及 Spring:

我没有太多的 Spring 实践经验,但 Baeldung 对在 Spring 中如何设置响应报头提供了很好的指导。


php

我对各种 PHP 框架不是很熟悉。查找了能够处理请求的中间件。对于单个响应,它的设置非常简单。

header("X-XSS-Protection: 1; mode=block");


Python 及 Django

Django 包含可配置的 安全中间件 ,通过该中间件来处理所有响应报头的设置。首先启用它们。

对于特定页面,可以将响应视为字典。Django 有一个处理缓存的特殊方法,如果试图以这种方式设置缓存响应报头,那么就应该调研后再使用。

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


总结

设置响应报头相对来说比较简单快捷。在数据保护、跨站脚本注入和点击劫持方面,站点安全性将会有相当大的提高。

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

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

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


链接: https://www.fly63.com/article/detial/4302

Web前端安全同样不可忽视,编写前端代码时保持安全意识

随着网络的普及,黑客进行网络攻击的手段越来也多,越来越复杂。前端的HTML、JavaScript、CSS、Flash等技术变成了前端攻击者和开发者的战场,网站安全问题也开始向前端倾斜。

AJAX请求真的不安全么?谈谈Web安全与AJAX的关系。

AJAX请求真的不安全么?AJAX请求哪里不安全?怎么样让AJAX请求更安全?本文包含的内容较多,包括AJAX,CORS,XSS,CSRF等内容,要完整的看完并理解需要付出一定的时间。

第三方 CSS 并不安全

第三方内容在其沙箱区域内具有强大的能力。如果你担心恶意用户诱使你的网站加载第三方资源,可以通过 CSP 用作防护手段,其可以限制加载图片,脚本和样式的来源。

WEB应用程序安全检查列表

检查页面隐藏或丢失的内容:检查webserver元数据文件,如:robots.txt, sitemap.xml,.DS_Store, .htaccess,检查搜索功能可能的注入或攻击方式,检查不同agent代理访问网站显示内容的是否一致

利用CSS注入(无iFrames)窃取CSRF令牌

要做到无iFrame,我将使用一种类似于之前我讨论过的方法:我将创建一个弹窗,然后在设置计时器后更改弹出窗口的位置。使用这种方法,我仍然可以加载受害者的CSS,但我不再依赖于受害者是否允许iFrame。

30 分钟理解 CORB 是什么

我当前的 chrome 版本是 v68,如果是 v66 或更低版本可能提示的警告信息略有不同。印象中只对 CORS 比较熟悉,CORB 是个什么鬼?好奇心迫使我想要了解一下它到底是什么,于是暂时把手头工作放下查了一些资料并花时间汇总了一下,就有了这篇文章

谈 target=‘_blank’的安全问题

大家都喜欢target=_blank, 因为新页面打开不影响原来的页面。但是这个存在安全问题, 由target=_blank打开的页面, 可以通过window.opener访问原来的窗口。遍可以简单的将网页导航到其他网站, 这就存在很多的安全隐患了, 比如钓鱼,这种问题解决起来也很简单, 在链接中加入rel=noreferrer noopener属性就可以了

Web安全测试检查单

Web安全测试检查单。上传功能:绕过文件上传检查功能,上传文件大小和次数限制。注册功能:注册请求是否安全传输,注册时密码复杂度是否后台检验,激活链接测试

一些安全相关的HTTP header

HTTP Strict-Transport-Security,简称为HSTS。X-Frame-Options:是否允许一个页面可在<frame>、<iframe>、<object>中展现的标记。X-XSS-Protection作用:防范XSS攻击。

第三方CSS安全吗?

第三方内容在其沙箱中具有很高的影响力。 虽然图像或沙盒iframe有着非常小的沙箱,但脚本和样式的作用范围却影响你的整个页面,甚至是整个站点。如果你担心用户会欺骗你的网站去加载第三方资源,可以使用CSP(内容安全策略)保证安全

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!