一、背景:
web程序需要知道网站的域名比较麻烦,需要使用HTTP的 host头字段:
<?php _SERVER["HTTP_HOST"] ?>
@app.route("/index/",methods=["GET"])
def index:
domain = request.headers.get("Host")
等等......
而且有些会把这个值不做HTML编码直接输出到页面:Joomla、Django、Gallery、others
二、常见的三种攻击行为:
1、密码重置:
邮件重置密码时,劫持了邮件的内容,将host替换掉,然后用户点击发起链接的事后,身份认证信息(这里一般指的是网站传给重置密码者的随机token)会自动传到恶意的host上面,从而导致攻击者可以劫持账户(已知身份认证信息)。
2、缓存污染:
Apache看所有host,nginx看最后一个host,Varnish看第一个。
所以可以通过在一个请求报文中加多个不同的host来污染缓存。
(现有架构下比较难攻击)因为之前的缓存节点可能污染区别host头,但现在的缓存一般都可以识别host头。
'''
GET /index.html HTTP/1.1
Host: www.baidu.com GET /index.html HTTP/1.1
Host: www.google.com
'''
这两种是绝对不会搞错的
3、跳转钓鱼
web开发程序重定向时候:
例如未登录访问页面会跳转回登录页面,而开发人员是无法得知自己开发的站点上线后的域名的,所以一般都是host获取。如果你重定向到登录页面所使用的HOST被攻击者污染了,改成了他的,很相似的域名,也转到仿造的一模一样的页面,用户再次输入密码,就会被盗取。
三、防御:
1、配置web程序使用server_name而不是host头
2、维护一个host白名单,难度较大。
3、UseCanonicalName选项开启。