不能只调大 package_max_length 来“解决”大报文攻击,它本质是缓冲区配置项,不是安全策略;盲目增大反而会放大 DoS 风险。
直接结论:不能只调大来“解决”大报文攻击,它本质是缓冲区配置项,不是安全策略;盲目增大反而会放大 DoS 风险。
为什么调整
不能防攻击
这个配置只是告诉 Swoole “单次接收的 HTTP 包(header + body)最大允许多大”,底层用的是固定大小内存缓存区。它不校验来源、不区分合法上传还是恶意构造的超长 payload,也不做流式解析或分块限速。
常见误操作是看到
就立刻把
设成 100MB —— 这等于给攻击者开了个内存喷射口:一个并发就能吃掉几十 MB 内存,100 个并发就可能拖垮整台机器。
真正需要的是分层防御:
接入层(如 Nginx)提前拦截超大请求(
)
应用层(Hyperf)对上传路径做白名单 + 文件类型 + 单文件大小校验
协议层(Swoole)用
做兜底,但值必须略大于业务最大合法包(比如 20MB),而非无上限
在 Hyperf 中正确设置
该配置必须写在
的
数组里,且仅对 HTTP server 生效(RPC 或 WebSocket server 需单独配):
注意三点:
Swoole 6.1.1
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
下载
值必须是整数,单位字节;
比硬写
更易维护
不要在
子项里重复设 —— 它属于全局
,不是 per-server
改完必须重启服务(
),热更新不生效
配合上传逻辑做实际防护
光调 Swoole 参数没用,Hyperf 的上传控制器必须自己校验。例如:
关键点:
用
而不是
—— Hyperf 的
对象已加载进内存,大小可即时读取
校验必须在 move 或写入前完成,否则攻击者可能先占满临时目录
如果走 OSS/MinIO 等对象存储,建议用预签名 URL + 前端直传,完全绕过 PHP 层接收大 body
容易被忽略的协程上下文陷阱
在协程环境下,
影响的不只是上传:所有 HTTP 请求(包括 POST JSON、表单、甚至恶意构造的超长 header)都会走同一缓冲区。如果你的接口接收大 JSON,又没做 body 解析限长,一样会触发错误。
更隐蔽的问题是:Swoole 默认不校验
是否真实 —— 攻击者发一个
但只发几个字节,Swoole 会一直等、直到超时或缓冲区填满。所以务必同时设置:
关闭(Hyperf 默认关,避免自动解析爆炸式 form data)
(如 5s),及时杀掉卡住的请求
用
控制 Worker 寿命,防止长期运行下内存缓慢泄漏
最终防线不在数字大小,而在是否让每个请求都明确知道自己能拿多少、该拒绝什么、以及失败后是否干净退出。
package_max_lengthpackage_max_lengthRequest Entity Too Largepackage_max_lengthclient_max_body_sizepackage_max_lengthpackage_max_lengthconfig/autoload/server.phpsettings'settings' => [
'package_max_length' => 20 * 1024 * 1024, // 20MB,不是 200MB
'enable_coroutine' => true,
'worker_num' => swoole_cpu_num() * 2,
],
20 * 1024 * 102420971520serverssettingsphp bin/hyperf.php startpublic function upload(UploadFile $file)
{
if ($file->getSize() > 10 * 1024 * 1024) {
throw new BadRequestHttpException('File too large, max 10MB');
}
if (! in_array($file->getMimeType(), ['image/jpeg', 'image/png'])) {
throw new BadRequestHttpException('Unsupported mime type');
}
// 后续保存...
}
$file->getSize()$_FILESUploadFilepackage_max_lengthContent-LengthContent-Length: 999999999http_parse_postrequest_slowlog_timeoutmax_request