swoole-src
swoole-src copied to clipboard
multipart/form-data 消息体不规范,会影响下一个规范的请求
Please answer these questions before submitting your issue. Thanks!
- What did you do? If possible, provide a simple script for reproducing the error.
第一个异常不规范的请求(即,缺少数据包最后的 boundary 标识,见第二个请求 红框 部分):

第二个正常请求:

- What did you expect to see?
第一个请求 drop 或者 http code 400
- What did you see instead?
两个请求都接收成功了,但是都不是完整的请求。
造成 swoole 第一个请求实际接收到的数据中丢失了 msg ,第二个请求的第一个参数中,多了第一个请求中 msg 的内容
- 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
- 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,只能分析出问题
感谢
是在一个连接里发送了2个 POST 请求吗?
是在一个连接里发送了2个 POST 请求吗?
不是,是两个不同的链接。事例中,第一个请求是 go 客户端发送的,第二个是 postman 发送的
PS,如果是同一个链接,同样也会出现问题
有具体的代码可以看看吗,会不会是两个请求同时共用了一个连接,看看这个连接是不是一个全局变量。
有具体的代码可以看看吗,会不会是两个请求同时共用了一个连接,看看这个连接是不是一个全局变量。
应该是不会的。服务端是 hyperf v2.2.14 in k8s,没有做特殊处理。
在排查问题期间,go 客户端是在 k8s 集群的另外一个 namespace 下,postman 是我本地电脑的。
再发现问题后,go 客户端针对这个问题也同时做了修复,才暂时避免了这个问题。我把 go 客户端的相关代码发下

图中的修改是第一个不规范请求的解决办法。
有没有试过用postman发送两次请求,看看会不会导致这样的问题
有没有试过用postman发送两次请求,看看会不会导致这样的问题
第一次请求是上图中的 go 发出的,则这一次有问题;
第二次请求是 postman 发出,则第二次这个也有问题;
第三次请求是 postman 发出,则第三次这个没有问题;
第四次请求是 postman 发出,则这一次没有问题;
第五次请求是 go 发出,则这一次有问题;
第六次请求是 postman 发出,则这次有问题;
总结:只要前一个请求是不规范的,无论下一次请求是否是规范的,都会被影响到
好像我这边也遇到这种情况