InfoQ Geekathon 大模型技术应用创新大赛 了解详情
写点什么

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

  • 2019-07-22
  • 本文字数:4500 字

    阅读完需:约 15 分钟

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

销售“安全记分卡”的公司正在崛起,并已开始成为企业销售的一个因素。这些公司组合使用 HTTP 安全报头和 IP 信誉来进行评级。不过,在很大程度上,公司的得分取决于对外开放网站上设置的安全响应报头。本文介绍了常用的安全响应报头及对应的推荐安全值,并给出了示例。


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


我调查了这些评级公司是如何计算公司安全性得分的,结果发现他们组合使用了 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 文件)等很少变更的页面,很适合使用缓存。既可以通过逐页设置的方式来实现,也可以通过在服务端配置使用正则表达式的方式来实现。


#  默认情况不使用缓存 Header set Cache-Control no-cache
# 静态资产设置成缓存1天<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$"> Header set Cache-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上的详情介绍页面


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



Access-Control-Allow-Origin 对应的数据流

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    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';
## 通用的安全响应报头 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
## 缓存策略 # 默认情况下不使用缓存 Header set Cache-Control no-cache Header set Expires: 0
# 设置静态资产缓存1天 <filesMatch ".(ico|css|js|gif|jpeg|jpg|png|svg|woff|ttf|eot)$"> Header set Cache-Control "max-age=86400, public" </filesMatch>
</IfModule>
复制代码

Nginx 设置

## CSPadd_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


活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2019-07-22 18:416003
用户头像

发布了 234 篇内容, 共 118.7 次阅读, 收获喜欢 540 次。

关注

评论 1 条评论

发布
用户头像
译者是infoQ官方人员吗?
2019-07-25 16:47
回复
没有更多了
发现更多内容

百度CTO王海峰:全栈AI技术加持,打造新一代大语言模型文心一言

飞桨PaddlePaddle

中国全屋智能市场将达万亿级,仅3.5%住宅渗透率拥有巨大潜力

Geek_2d6073

adobe安装提示错误“Error:SyntaxError:JSON Parse error:Unexpected EOF”

互联网搬砖工作者

开源订单管理系统

源字节1号

开源 软件开发 小程序开发

快速掌握网站监控关键数据:仪表盘的创建与管理

云智慧AIOps社区

监控 监控宝 监控工具 云智慧 网站监控

强烈推荐!阿里架构师纯手写的大型分布式项目《凤凰架构》手册

开心学Java

分布式 分布式系统 java 构架

JVM 堆体系结构及其内存调优

做梦都在改BUG

Java JVM

金三银四互联网大厂精选1160道Java面试题答案整理(2023最新版)

架构师之道

编程 程序员 java面试

CCF BDCI“大数据平台安全事件检测与分类识别”赛题,奇点云夺冠

奇点云

数据安全 奇点云 个人信息保护

低内存、高性能,磁盘索引可以这样玩

Zilliz

非结构化数据 Milvus 向量数据库

全网爆火!阿里内部产出的Java面试核心手册震撼开源了,太香了

开心学Java

Java 面试 春招 java Java八股文 Java 面试题

百度文库接入文心一言,国内首个生成式AI文档服务即将上线

Geek_2d6073

企业数智化转型不仅是可行的,还是必行!

加入高科技仿生人

人工智能 低代码 制造业 数智化

科技+卫生=智慧公厕,城市焕然一新!

光明源智慧厕所

智慧城市

低代码引擎动作编排

高宏数智低代码

低代码

ByteHouse:基于ClickHouse 的实时计算能力升级

字节跳动数据平台

大数据 云原生 flink 消费 kafka Clickhouse 企业号 3 月 PK 榜

软件测试/测试开发丨接口测试必备技能-常见接口协议解析

测试人

软件测试 自动化测试 测试开发

软件测试/测试开发丨一文带你了解接口测试价值与体系

测试人

软件测试 自动化测试 测试开发

软件测试/测试开发丨app自动化测试(iOS)元素定位(新手篇)

测试人

软件测试 自动化测试 测试开发

初学后端,如何做好表结构设计?

王中阳Go

Go golang 数据库 表结构 golang 面试

苹果M1芯片的Mac怎么关闭SIP?M1 mac关闭Sip方法教程!

互联网搬砖工作者

头部险企如何打造低代码数据集市,快速构建指标体系

Kyligence

金融科技 指标体系

Flink 在中泰证券的实践与应用

Apache Flink

大数据 flink 实时计算

数字孪生的安全挑战和机遇

Openlab_cosmoplat

开源社区 数字孪生

专业、简单、稳定,融云重新定义互联网通信云服务

融云 RongCloud

互联网 数字化 办公 泛娱乐 通讯

好用的Java开发工具:IntelliJ IDEA 2022v2022.3.3汉化激活版

真大的脸盆

Java Mac Mac 软件 Java 开发

CloudCanal 落地 StarRocks 数据迁移同步的实践与思考

StarRocks

数据库

使用流水线插件实现持续集成、持续部署

北京好雨科技有限公司

Kubernetes CI/CD rainbond

还在stream中使用peek?不要被这些陷阱绊住了

程序那些事

Java java8 程序那些事 JDK20

如何通过Java代码在Word中创建可填充表单

在下毛毛雨

Java 表单 word文档

2023中国儿童防敏市场发展洞察

易观分析

医疗 防敏 儿童

  • 扫码添加小助手
    领取最新资料包
最全HTTP安全响应头设置指南_语言 & 开发_Charlie Belmer_InfoQ精选文章