http请求走私(request smuggling)原理解析
原理
一般服务器端架构为:web服务器 + 应用服务器,web服务器比如nginx,apache httpd等(也可以叫反向代理),应用服务器比如apache tomcat,spring cloud等。
web服务器用来处理高并发客户端请求,并转发给后端应用服务器。
通常为了减少网络连接次数,提高处理速率,前端浏览器和web服务器之间会保活,即keep-alive;web服务器和应用服务器之间的tcp连接也会保活。保活:即复用tcp连接,在一个连接里面传输多个http请求
那么问题来了,一个tcp连接传输多个http请求,web服务器和应用服务器都怎么区分多个的http请求?
根据rfc标准,可根据content-length:size和Transfer-Encoding:chunked等方式对复用tcp中的多个http请求进行分割
content-length是读取指定size的body
Transfer-Encoding:chunked,传输body格式[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n],会根据0\r\n\r\n来判断结尾
问题原因来了:不同的服务器分割请求的标准不一样。对同一段tcp内容,前后端服务器获取到的http请求个数不一致,就导致了请求走私
前后端服务器分割http的方式组合起来有四种,都会产生响应危害
前端\后端 | Content-Length | Transfer-Encoding |
Content-Length | ||
Transfer-Encoding |
详细原理解析见
https://paper.seebug.org/1048/#1
原版英文版
https://portswigger.net/web-security/request-smuggling
解决办法
选择分割http请求方式一致的前后端服务器(并没有具体推荐)
(禁用keep-alive等都是临时解决措施)