swoole-src icon indicating copy to clipboard operation
swoole-src copied to clipboard

multipart/form-data 消息体不规范,会影响下一个规范的请求

Open yansongda opened this issue 4 years ago • 7 comments

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a simple script for reproducing the error.

第一个异常不规范的请求(即,缺少数据包最后的 boundary 标识,见第二个请求 红框 部分):

截屏2021-11-04 下午7 16 20

第二个正常请求:

截屏2021-11-04 下午7 16 26

  1. What did you expect to see?

第一个请求 drop 或者 http code 400

  1. What did you see instead?

两个请求都接收成功了,但是都不是完整的请求。

造成 swoole 第一个请求实际接收到的数据中丢失了 msg ,第二个请求的第一个参数中,多了第一个请求中 msg 的内容

  1. What version of Swoole are you using (show your php --ri swoole)?
root@yansongda-app-5c4f7d6469-gxd57:/www# php --ri swoole

swoole

Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 4.8.1
Built => Nov  1 2021 11:13:25
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.1.1k  25 Mar 2021
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
zlib => 1.2.11
brotli => E16777225/D16777225
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

hyperf v2.2.14 in k8s

从以上描述中,我们可以思考发现

表面问题:

当 multipart/form-data 时,如果第一个请求不规范(示例中是缺少最后的 boundary 标识)会对第二个请求造成影响,应该是 沾包?

实际问题:

1、没有对 header 中的 content-length 进行检验(查看了 swoole 代码,确认中确实没有对 length 进行校验)

2、根据源码,发现只对 boundary 标识而进行的数据分隔,所以第一个请求对第二个正常请求造成了影响,估计可能会产生安全问题?

由于能力有限不能提供相关 PR,只能分析出问题

感谢

yansongda avatar Nov 04 '21 14:11 yansongda

是在一个连接里发送了2个 POST 请求吗?

matyhtf avatar Nov 04 '21 23:11 matyhtf

是在一个连接里发送了2个 POST 请求吗?

不是,是两个不同的链接。事例中,第一个请求是 go 客户端发送的,第二个是 postman 发送的

PS,如果是同一个链接,同样也会出现问题

yansongda avatar Nov 05 '21 00:11 yansongda

有具体的代码可以看看吗,会不会是两个请求同时共用了一个连接,看看这个连接是不是一个全局变量。

NathanFreeman avatar Nov 05 '21 01:11 NathanFreeman

有具体的代码可以看看吗,会不会是两个请求同时共用了一个连接,看看这个连接是不是一个全局变量。

应该是不会的。服务端是 hyperf v2.2.14 in k8s,没有做特殊处理。

在排查问题期间,go 客户端是在 k8s 集群的另外一个 namespace 下,postman 是我本地电脑的。

再发现问题后,go 客户端针对这个问题也同时做了修复,才暂时避免了这个问题。我把 go 客户端的相关代码发下

截屏2021-11-05 上午9 50 38

图中的修改是第一个不规范请求的解决办法。

yansongda avatar Nov 05 '21 01:11 yansongda

有没有试过用postman发送两次请求,看看会不会导致这样的问题

NathanFreeman avatar Nov 05 '21 02:11 NathanFreeman

有没有试过用postman发送两次请求,看看会不会导致这样的问题

第一次请求是上图中的 go 发出的,则这一次问题;

第二次请求是 postman 发出,则第二次这个也问题;

第三次请求是 postman 发出,则第三次这个没有问题;

第四次请求是 postman 发出,则这一次没有问题;

第五次请求是 go 发出,则这一次问题;

第六次请求是 postman 发出,则这次问题;

总结:只要前一个请求是不规范的,无论下一次请求是否是规范的,都会被影响到

yansongda avatar Nov 05 '21 02:11 yansongda

好像我这边也遇到这种情况

shuipf avatar Apr 11 '22 05:04 shuipf