Yukang's Page

Host Header Attack

什么是Host Header Attack

Rails最近被HackerOne报了两次Host Header Attack漏洞,官方还没有给出解决方案,详细请看这个issue:

https://github.com/rails/rails/issues/29893

这是一种比较老的攻击,在Php的web框架里也可能存在问题。

其攻击手法是攻击者在http请求头如Host/X-Forwarded-Host/X-Forwarded-Scheme中注入恶意内容,而web应用如果信任这些请求头并使用其作为url的一部分,从而导致页面中产生恶意链接。这种攻击可导致Open redirect, Cache poisoning, Password reset poisoning等,详细的介绍可以参考下面的链接

Rails里面X-Forwarded-Host 这个请求头总是被信任,并被url_for用于生成url,包括但不限于redirect时被生产的链接被篡改成恶意链接,即使指定的是相对路径(如 redirect_to root_path)。除了使用url_for, url helper等方法会受到攻击外,如果系统中使用了request.base_url,request.host等作为url的一部分,也会受到攻击,这是因为Rack::Request中相关方法都是直接信任了相应的请求头。

由于Rails官方未给出解决方案,同事参考了几篇文章,初步整理出一个解决方案:

nginx配置

a) 每个项目的server块配置中使用server_name指定已知的有效域名,然后去掉敏感的Header请求头

server {
server_name www.example.com;
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-Port "";
proxy_set_header X-Forwarded-Scheme "";
proxy_set_header X-Forwarded-Ssl "";
}

b) 配置一个dummy host,用于匹配无效host的请求。

# dummy.conf
# Server for catch all unknown domains.
server {
listen *:80 default_server;
listen *:443 default_server;
listen [::]:80 default_server ipv6only=on;
listen [::]:443 default_server ipv6only=on;
ssl_certificate /path/to/dummy.crt;
ssl_certificate_key /path/to/dummy.key;
server_name _;
return 444;
}

注意上述配置包含了https的配置,其中用到一个dummy证书,这个可以是个自签证书,可以使用以下命令生成:

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout dummy.key -out dummy.crt

参考:https://www.codem.com.au/blog/nginx-reject-unknown-domains-ssl/ ,如果不支持ssl,将上面的配置中ssl相关信息删除即可。

配置后,使用

curl -H'Host: evil.com'
http://www.example.com/

进行访问,nginx将返回空响应。需要注意的是,增加dummy host后,如果ELB等负载均衡器使用IP对nginx进行健康检查,可能导致nginx被误认为失去响应,这个需要跟运维进一步确认。

Kong解决方案

经过我的实验,Kong里面是认了Host来匹配API的,所以像上面的evil.com如果没有在Kong里面配置,结果是会一个错误结果:

{"message":"no API found with those values"}

所以剩下的就是需要把那些headers在Kong里面去掉,这个事情是在Kong里面现成的插件的,参考: request-transformer

Rails配置

如果觉得Nginx配置太麻烦,也没有使用Kong来做前端gateway,Rails也可以通过配置和Gem包来防范:

  • 配置default_url_options和asset_host

在文件config/environments/production.rb里配置:

config.action_controller.default_url_options = {host: "www.yoursite.com"}
config.action_controller.asset_host = "www.yoursite.com
  • 使用rack-headers_filter gem删除敏感http请求头

我看了下这个gem只有3个星星(截止2017-09-13),但实际上这个gem的代码量非常少,我review了一下,没发现什么问题。配置请看:

https://github.com/pusher/rack-headers_filter

发表评论

BuckleScript and Reason

BuckleScript虽然我不是前端工程师,不过因为喜欢 OCaml,所以偶尔关注 BuckleScript 有一段时间了,今天又花时间看了看文档和代码。BuckleScript 是张宏波主导开发的开源项目,『有希望成为第一个完全由国人设计主导实现并被世界各地广泛使用的编译器』,不过是 .....
阅读全文

《深度工作-如何有效使用每一点脑力》读后

深度工作这本书主要讲解了一些时间和精力管理方面的东西,人到了一定年龄就会觉得时间不够用,日子过得太快,每天觉得都没干什么就过去了。工作几年后这种感觉时不时袭来。反而是如果某段时间一直有一个阶段性的目标,就会觉得很踏实,进度和效率也可以。那种完全沉浸在思考中的状态真的也并不是累,相反所得到 .....
阅读全文

Kong的0.11.0版本

Kong发布了新的版本0.11.0,从这里开始区分了社区版本和商业版。这次改动比较大的是丢弃了serf,这样整个Kong节点之间的缓存同步方式变化了。开发者给出的理由如下: 依赖serf,serf并不属于Nginx/OpenResty 这种依赖相互间通信来同步的机制对于deploym .....
阅读全文

Lua时间处理

我需要用Lua处理一个与时间相关的问题,比如我们在配置文件里面配置一个日期(北京时间),然后在Openresty里面判断当前时间是否在这个日期之前或者之后来做对应的逻辑。 Lua的时间处理还有点麻烦,主要是自带的相关库函数比较少。 os.time() &l .....
阅读全文

使用 exercism 来练手学语言

有时候我们想学一门编程语言,但是光看看书和代码用例总是找不到感觉,这时候我们应该尝试写点不短不长的程序片段,可能是一个函数,或者是实现一个简单的算法。最近我发现这个叫做exercism.io的网站不错,自己也在闲余时间在上面看看。 这里支持30多种编程语言,每种语言大概有80个左右的小问 .....
阅读全文

从 Jekyll换成Hexo

昨天看到自己的 Blog 在移动端显示丑死了,所以想着优化一下,找一个 mobile first 的风格试试。顺便把 blog 从 jekyll 换成了 Hexo。最后找到这个 hexo 的主题非常顺眼,便拿来用了,感谢yanm1ng为大家提供如此优秀的主题。回想起自己之前用过搜狐博客, .....
阅读全文

Kong源码分析: 事件

Kong的缓存更新很多依赖于事件,而事件看起来是相对来说比较复杂、也是最有趣的一部分。 worker模型假设我们对Kong做了一个更改的请求,这个请求通常是通过admin_api这个路由处理的。也就是说最终执行数据库操作的动作是在一个Nginx worker进程里。因为操作了数据库所以我 .....
阅读全文

Kong源码分析: 缓存

Nginx里的缓存使用在Kong里面我们缓存的内容大部分是配置,不管是API本身的配置还是插件相关的配置,缓存之后就存储在内存中。 Kong里的缓存基础代码在tools/database_cache.lua文件里面。这里又分两种类型的缓存,一种是shared dict, 一种是使用lua .....
阅读全文

Kong源码分析: 插件

插件的强大之处在我自己使用 Kong 的过程中,最方便的还是在于 Kong 的强大的插件机制。 Nginx 本身提供了提供模块开发机制,但是相对来说更底层一些,并且需要使用 C/C++ 来开发,对于很多开发人员来说 Nginx 仍为一个黑盒。OpenResty 集成了很多好用插件,并提供 .....
阅读全文
Prev Next