Multiple Host Ambiguities
此篇博客是学习陈建军博士的一篇关于<<Host of Troubles: Multiple Host Ambiguities in HTTP Implementations>>的论文,以下是建军博士的论文和 PPT 网址。
论文地址:Host of Troubles: Multiple Host Ambiguities in HTTP Implementations :
http://www.icir.org/vern/papers/host-of-troubles.ccs16.pdf
作者 PPT地址: http://free.eol.cn/edu_net/edudown/spkt/chenjianjun.pdf
Host of Troubles官网:https://hostoftroubles.com/
首先我们回顾下 HTTP协议的请求头部
常用头域:
常用头域名称 |
作用描述 |
Cache-Control |
缓存控制 |
Connection |
HTTP 1.1默认是支持长连接的(Keep-Alive),如果不希望支持长连接则需要在此域中写入close |
Date |
表明消息产生的日期和时间 |
Pragma |
|
Trailer |
|
Transfer-Encoding |
告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 |
Upgrade |
给出了发送端可能想要”升级”使用的新版本或协议 |
Via |
显示了报文经过的中间节点(代理、网关) |
请求头域:
请求头域名称 |
作用描述 |
Accept |
指明请求端可以接受处理的媒体类型 |
Accept-Charset |
指明请求端可以接受的字符集 |
Accept-Encoding |
指明请求端可以接受的编码格式 |
Authorization |
授权 |
Expect |
允许客户端列出某请求所要求的服务器行为 |
From |
提供了客户端用户的E-mail地址 |
Host |
指明请求端的网络主机和端口号 |
If-Match |
服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-Match(值为响应的ETag),服务端接收后判断ETag是否相同,若相同则处理请求,否则不处理请求。 |
If-Modified-Since |
客户端在请求某一资源文件时,在头部加上If-Modified-Since(值为该资源文件的最后修改时间),服务端接收后将客户端上报的修改时间与服务器存储的文件的最后修改时间做对比,如果相同,说明资源文件没有更新,返回304状态码,告诉客户端使用原来的缓存文件。否则返回资源内容。 |
If-None-Match |
服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-None-Match(值为响应的ETag),服务端接收后判断ETag是否相同,若相同,说明资源没有更新,返回304状态码,告诉客户端使用原来的缓存文件。否则返回资源内容。 |
If-Range |
该头域与Range头域一起使用,服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-Range(值为响应的ETag),服务端接收后判断ETag是否相同,若相同,则返回状态码206,返回内容为Range指定的字节范围。若不相同,则返回状态码200,返回内容为整个实体。 |
If-Unmodified-Since |
客户端在请求某一资源文件时,在头部加上If-Modified-Since(值为该资源文件的最后修改时间),端接收后将客户端上报的修改时间与服务器存储的文件的最后修改时间做对比,如果相同,则返回资源内容,如果不相同则返回状态码412。 |
Max-Forwards |
配合TRACE、OPTIONS方法使用,限制在通往服务器的路径上的代理或网关的数量。 |
Proxy-Authorization |
代理授权 |
Range |
表示客户端向服务端请求指定范围的字节数量:Range:bytes=0-500表示请求第1个到第501个的字节数量。Range:bytes=100-表示请求第101到文件倒数第一个字节的字节数量。Range:bytes=-500表示请求最后500个字节的数量。Range可以同时指定多组(Range:bytes=500-600,601-999)。并不是所有的服务端都支持字节范围请求的,如果支持字节范围请求,服务端会返回状态码206,若不支持则会返回200,客户端需要根据状态码来判断服务端是否支持字节范围操作。此域可用于断点下载,即在断点处请求后面的内容,也可用于多线程下载同一个文件,每个线程负责一个文件的一部分下载工作,多个线程协同完成整个文件的下载。 |
Referer |
用于指定客户端请求的来源,是从搜索引擎过来的?还是从其它网站链接过来的?服务器根据此域,有时可以用做防盗链处理,不在指定范围内的来源,统统拒绝。 |
TE |
指明客户端可以接受哪些传输编码。 |
实体头域:
实体头域名称 |
作用描述 |
Allow |
指明被请求的资源所支持的方法,如GET、HEAD、PUT |
Content-Encoding |
指明实体内容所采用的编码方式 |
Content-Language |
指明实体内容使用的语言 |
Content-Length |
指明请求实体的字节数量 |
Content-Location |
可以用来为实体提供对应资源的位置 |
Content-MD5 |
指定实体内容的MD5,用于内容的完整性校验(base64的128位MD5) |
Content-Range |
|
Content-Type |
指定实体的媒体类型 |
Expires |
指明实体的过期时间 |
Last-Modified |
指明实体最后被修改的时间 |
HTTP协议中最关键的字段--Host,如果Host理解出现歧义,后果很严重,以下介绍多种多 Host 造成任意两个链路中歧义的原因.
1、多Host头
发送带有多 Host 的http 请求,downstream 与 upstream 可能理解成不同的 host地址,此情况出现条件较为复杂。
2、Host头增加前后空格
downstream去掉了前置空格,upstream不认识前置空格,直接使用了b.com
3、request uri是绝对路径
upstream认识scheme标识的Host
akamai未遵循
作者讲解了如下攻击:
1、任意网站Squid透明缓存污染
针对 squid重灾区,通过request-uri路径标识进行欺骗,首先发送欺骗请求至 attack.comg攻击者自己搭的服务器,squid缓存判断attack.com == 1.1.1.1 记录 cache,cache host被记录为 victim.com,造成之后命中 cache都被定向到 attack 恶意攻击网站.
squid缓存污染可污染任意网站,危害很严重,在小区缓存或校园 cache都可能严重的污染定向问题。
2、Co-hosting透明缓存污染
针对 host 空格的解析出现问题
3、CDN缓存污染
作者针对alibaba解析多 host时出现的 host 顺序调整进行测试,出现CDN-> Squid host倒置的问题
4、防火墙绕过
5、WAF绕过
request URI scheme attack
出现多 host 攻击或者 cache污染之所以严重,难以处理之处也在于 Server根本无法处理,就连察觉是那一路由部分出现问题都不好定位。
作者提及解决方案:
- RFC 7230 [ 6 ]明确指定的要求以及多headers must be 拒绝以及给出400错误请求。对于厂商,不同的系统应该完全遵循RFC7230,消除与其他系统之间的歧义
- ISP应该及时更新透明缓存软件
- HTTPS并启用pre load HSTS
- jon postel法则的局限性: be conservative in what you do, B3 liberal you accept from others.
- 给出参考代码,描述遵循标准
- 设计上避免
- 网络框架实现跟上RFC标准