首页/新闻资讯/正文详情

aiohttp WebSocket 关闭码校验修复:拒绝对端 Close 帧中的 1006(ABNORMAL_CLOSURE)

发布时间:2026/9/27 10:56:59 来源:云帆数科 栏目:资讯中心
aiohttp WebSocket 关闭码校验修复:拒绝对端 Close 帧中的 1006(ABNORMAL_CLOSURE)
后端Web框架WebSocket【免费下载链接】aiohttpAsynchronous HTTP client/server framework for asyncio and Python项目地址https://gitcode.com/gh_mirrors/ai/aiohttp点击查看免费下载导读本文围绕 aiohttp 的 bugfix 变更CHANGES/13536.bugfix.rst展开WebSocket Reader 此前会错误地接受对端 Close 帧中携带的关闭码1006而根据 RFC 64551006属于保留码禁止出现在网络传输的 Close 帧中。文章将结合仓库源码与测试用例剖析该问题的成因、修复后的校验逻辑、Python/Cython 双实现路径以及1006在 aiohttp 内部作为本地状态码WSCloseCode.ABNORMAL_CLOSURE的正当用法帮助读者理解 WebSocket 协议合规性校验的底层实现。一、问题背景RFC 6455 中的关闭码语义WebSocket 协议RFC 6455定义了 Close 控制帧用于在连接两端主动终止会话时传递一个 2 字节的关闭状态码close code和可选的文本原因。关闭码被划分为几个区间1000–2999协议保留区间其中1000–1015是固定语义的预定义码3000–3999留给库、框架和应用自行注册使用4000–4999供私有应用使用。其中1006ABNORMAL CLOSURE是一个特殊的存在它被 RFC 6455 第 7.4.1 节定义为连接在缺少 Close 帧的情况下异常关闭的语义仅供本地实现内部标记使用绝不能作为帧内容在网络上发送。同理1004保留、1005无状态码、1015TLS 握手失败也都是禁止上线的保留码。aiohttp 在 aiohttp/_websocket/models.py 中通过WSCloseCode枚举完整登记了这些预定义码class WSCloseCode(IntEnum): OK 1000 GOING_AWAY 1001 PROTOCOL_ERROR 1002 UNSUPPORTED_DATA 1003 ABNORMAL_CLOSURE 1006 INVALID_TEXT 1007 POLICY_VIOLATION 1008 MESSAGE_TOO_BIG 1009 MANDATORY_EXTENSION 1010 INTERNAL_ERROR 1011 SERVICE_RESTART 1012 TRY_AGAIN_LATER 1013 BAD_GATEWAY 1014注意ABNORMAL_CLOSURE 1006是枚举成员之一aiohttp 在本地用它标记连接异常中断但这不意味着它可以被写入 Close 帧对外发送——这正是本次 bugfix 修复的边界问题。二、问题本身Reader 误接受对端下发的 1006在修复之前WebSocket Reader 在解析 Close 帧时对关闭码的合法性检查存在漏洞导致对端peer在 Close 帧中携带1006时会被当作合法值接受而不是按协议要求以1002 PROTOCOL_ERROR拒绝。这个问题的严重性在于违反 RFC 6455 的显式规定1006不应出现在线上帧中在 aiohttp 内部1006有专门含义连接异常关闭若被当作对端显式关闭码透传给上层应用会造成语义混淆——应用层会分不清对端发来了 1006与本地检测到连接异常协议解析器作为安全边界接受非法状态码可能成为畸形/不规范实现混入的入口。三、修复方案ALLOWED_CLOSE_CODES 白名单校验修复的核心在 aiohttp/_websocket/reader_py.py。源码通过构造一个允许上线的关闭码集合显式把1006排除在外# ABNORMAL_CLOSURE is used internally, should never be accepted from a client. # https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1 ALLOWED_CLOSE_CODES {int(i) for i in WSCloseCode} - { int(WSCloseCode.ABNORMAL_CLOSURE) }这一行注释直接点明了本次修复的设计意图ABNORMAL_CLOSURE仅供内部使用绝不应从对端接受。随后的 Close 帧处理逻辑reader_py.py在解出 2 字节关闭码后执行完整的合法性判定elif opcode OP_CODE_CLOSE: payload_len len(payload) if payload_len 2: close_code UNPACK_CLOSE_CODE(payload[:2])[0] # https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.2 if close_code 4999 or ( close_code 3000 and close_code not in ALLOWED_CLOSE_CODES ): raise WebSocketError( WSCloseCode.PROTOCOL_ERROR, fInvalid close code: {close_code}, ) ...校验规则可以拆解为两条条件判定结果close_code 4999含5000–65535超出合法区间报1002 PROTOCOL_ERRORclose_code 3000且不在ALLOWED_CLOSE_CODES中属于保留/禁止码如1004、1005、1006、1015报1002 PROTOCOL_ERROR由于ALLOWED_CLOSE_CODES是从WSCloseCode枚举全集剔除1006后得到的因此1006必然落入第二条分支被拒绝。修复后任何携带1006的 Close 帧都会触发WebSocketErrorcode1002该异常会经由feed_data的异常捕获路径reader_py.py写入队列最终以上层可见的协议错误形式暴露给调用方。此外Close 帧还有其他合规性校验payload 长度必须为 0 或 ≥21 字节的 payload 会被判定为非法见 reader_py.pypayload 中的文本部分必须是合法 UTF-8否则报1007 INVALID_TEXT。四、Python 与 Cython 双实现修复如何覆盖两条代码路径aiohttp 的 WebSocket 解析器存在双实现架构纯 Python 实现aiohttp/_websocket/reader_py.pyCython 加速实现aiohttp/_websocket/reader_c.pxd 定义了WebSocketReader/WebSocketDataQueue的 C 级接口模块入口 aiohttp/_websocket/reader.py 负责按运行环境选择实现当NO_EXTENSIONS为真或 Cython 扩展导入失败时回退到 Python 版本否则优先加载编译后的reader_c版本。ALLOWED_CLOSE_CODES这个集合在 reader_c.pxd 中被声明为cdef set与 Python 实现共享同一份语义定义——因此本次校验修复对两条代码路径同时生效无论用户安装的是纯 Python 包还是带 Cython 扩展的预编译 wheel行为一致。从实现细节看_handle_frame的 close 分支同样在 Cython 版本中通过cpdef暴露reader_c.pxd关闭码的解析借助UNPACK_CLOSE_CODE字节解包辅助函数完成确保 Python 与 C 路径的校验结果严格等价。五、测试验证保留码参数化用例仓库测试 tests/test_websocket_parser.py 为本次修复提供了直接的回归保护pytest.mark.parametrize(code, (1004, 1005, 1006, 1015)) def test_close_frame_reserved_code(parser: PatchableWebSocketReader, code: int) - None: # https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1 # 1004, 1005, 1006 and 1015 are resreved and forbidden as a # status code in a Close frame on the wire. 1006 is a WSCloseCode member # (aiohttp uses it locally), so it must still be rejected on receipt. data build_close_frame(codecode) with pytest.raises(WebSocketError) as ctx: parser._feed_data(data) assert ctx.value.code WSCloseCode.PROTOCOL_ERROR该测试的注释与源码注释相互印证1006虽然是WSCloseCode枚举成员本地使用但在接收时必须拒绝。测试将1004、1005、1006、1015四个保留码统一参数化确保它们全部被解析器以PROTOCOL_ERROR拒绝。同一测试文件中还有配套的边界用例test_websocket_parser.py覆盖5000、9999、65535等超出4999上限的非法关闭码与白名单逻辑形成完整闭环。六、1006 在 aiohttp 内部的正当用法ABNORMAL_CLOSURE修复并没有移除1006的枚举定义——它在 aiohttp 内部依然承担重要职责只是使用场景被严格限定在本地状态标记而非线上帧内容。在功能测试中可以看到WSCloseCode.ABNORMAL_CLOSURE被用来断言连接异常关闭的结果tests/test_client_ws_functional.py 等多处断言resp.close_code is WSCloseCode.ABNORMAL_CLOSURE即客户端在连接被异常中断未收到 Close 帧时本地记录关闭码为1006tests/test_web_websocket_functional.py 等服务端测试同样用ws.close_code WSCloseCode.ABNORMAL_CLOSURE断言异常断开场景。也就是说1006在 aiohttp 的语义是对端没有发送 Close 帧就断开了连接——这是本地检测到的异常状态close_code属性会以ABNORMAL_CLOSURE呈现给应用层。这与从线上帧中解析出 1006是完全不同的两条路径。本次 bugfix 的意义正在于堵住后一条路径既然1006是本地状态的专属标记那么任何从对端帧中宣称1006的行为都必然是非法的协议数据必须被解析器以1002 PROTOCOL_ERROR拒绝而不能混入本地状态标记中。七、对使用者的影响与升级建议行为变化升级到包含该修复的版本后如果对端客户端或服务端在 Close 帧中携带1006aiohttp 不再将其透传为关闭码而是抛出WebSocketErrorcode1002并触发连接关闭。这符合 RFC 6455 对保留码的规定属于协议合规性收紧。自查对端实现若你的应用需要与某些不规范实现的 WebSocket 服务端/客户端互通请确认对端不会在 Close 帧中发送1006或1004、1005、1015。规范的做法是仅在本地用1006标记连接异常线路上永远不发送它。应用层判断逻辑不变ws.close_code仍会在连接异常中断时返回WSCloseCode.ABNORMAL_CLOSURE本地语义这部分行为未受影响受影响的是对端帧中显式携带 1006这一非法输入的处理。关注测试入口如需验证自己的构建版本是否包含该修复可直接运行 tests/test_websocket_parser.py 中的test_close_frame_reserved_code参数化用例观察1006是否被拒绝。小结本次 bugfix 以一段精巧的白名单集合ALLOWED_CLOSE_CODES WSCloseCode 全集 - {1006}修复了 WebSocket Reader 对保留关闭码的校验漏洞使 aiohttp 在拒绝非法关闭码与本地使用 1006 标记异常关闭两条语义之间划清了边界。从 models.py 的枚举定义、reader_py.py 的校验实现到 reader_c.pxd 的 Cython 双路径覆盖再到 test_websocket_parser.py 的回归测试仓库中形成了完整一致的协议合规性闭环——这正是 aiohttp 作为 asyncio 生态 WebSocket 实现所应具备的严谨性。赞分享后端Web框架WebSocket【免费下载链接】aiohttpAsynchronous HTTP client/server framework for asyncio and Python项目地址https://gitcode.com/gh_mirrors/ai/aiohttp点击查看免费下载相关推荐aiohttp WebSocket CLOSE 帧状态码校验按 RFC 6455 拒绝越界关闭码4999的协议错误处理aiohttp WebSocket CLOSE 帧状态码校验按 RFC 6455 拒绝越界关闭码 4999的协议错误处理 导读 本文围绕 aiohttp后端Web框架WebSocketaiohttp WebSocket 分片消息协议校验修复严格按 RFC 6455 拒绝分片间注入的数据帧aiohttp WebSocket 分片消息协议校验修复严格按 RFC 6455 拒绝分片间注入的数据帧 本篇技术指南围绕 aiohttp 的 WebSock后端Web框架WebSocketaiohttp WebSocket 大消息整型溢出漏洞修复解析从 max_msg_size 校验到 1009 关闭码aiohttp WebSocket 大消息整型溢出漏洞修复解析从 max_msg_size 校验到 1009 关闭码 导读 本文基于 aiohttp 官方变更后端Web框架WebSocket上一篇Unlock Music 使用指南3 步在浏览器中解锁加密音乐无需安装下一篇craft-agents-oss 0.2.33 版本技术解析OAuth 认证统一、~/.claude.json 自动修复与稳定性加固创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

3步搞定老板洗碗机逻辑:手写实现避坑指南
3步搞定老板洗碗机逻辑:手写实现避坑指南

3步搞定老板洗碗机逻辑:手写实现避坑指南 复制来的代码跑不通,报错满屏飘,这时候别急着换库。把源码扒开看,你会发现那些所谓的“智能”不过是一堆硬编码的逻辑判断。想要彻底搞懂老板洗碗机的控制逻辑,或者在嵌入式项目中 手写实现… · 2026/9/27 10:55:20

5年避坑指南:女剑魔刷图加点速查手册,面试不再卡壳
5年避坑指南:女剑魔刷图加点速查手册,面试不再卡壳

5年避坑指南:女剑魔刷图加点速查手册,面试不再卡壳 面试官盯着屏幕,问:“你这个女剑魔刷图加点逻辑,底层是怎么实现的?为什么这里要异步,那里要同步?”你愣了3秒,脑子里一片空白。… · 2026/9/27 10:55:34

Flet flet-ads PrecisionType 详解:广告付费价值精度枚举的语义与实战用法
Flet flet-ads PrecisionType 详解:广告付费价值精度枚举的语义与实战用法

前端跨平台桌面应用移动开发 【免费下载链接】flet Build realtime web, mobile and desktop apps in Python only. No frontend experience required. 项目地址: https://gitcode.com/gh_mirrors/fl/flet 点击查看 免费下载 导读 PrecisionType 是 Flet 官方扩展… · 2026/9/21 22:52:50

驱动能跑却会崩?量产级嵌入式驱动的稳定性攻坚指南
驱动能跑却会崩?量产级嵌入式驱动的稳定性攻坚指南

在实际的驱动开发项目里,"驱动能跑了"和"驱动没问题了"是两句经常被混为一谈的话。如果你做嵌入式开发的时间够长,一定遇到过我前面描述的那一幕:代码在开发板上调通了,串口输出正常,功能测试全过… · 2026/9/27 10:56:52

群辉做网站服务器python到底多少钱?避坑指南
群辉做网站服务器python到底多少钱?避坑指南

群辉做网站服务器python到底多少钱?避坑指南 模板网站太丑不够用,想自己用Python搞个服务器部署,到底要花多少钱?这是很多刚入行的东北前端兄弟常问我的问题。别急,咱们今天不整那些虚头巴脑的理论,直接上干货,把成本算得明明白白,让你心… · 2026/9/27 10:56:46

Agilent 53150A微波频率计原理与高精度测量实践
Agilent 53150A微波频率计原理与高精度测量实践

1. 这台“老将”到底能干啥?——Agilent 53150A不是万能表,但它是频率测量领域的“精密标尺”Agilent 53150A 频率计,这个名字在电子测试实验室里,尤其是做射频、微波、时钟源校准和通信系统验证的工程师嘴里,从来不是… · 2026/9/27 10:56:46

5557连接器选型与供应商对比实战指南
5557连接器选型与供应商对比实战指南

干硬件和供应链这行,最烦的就是找料。芯片缺、电阻涨价这些还能忍,最容易被忽视的反而是连接器这种不起眼的玩意儿——画原理图的时候它就是一个小方块,等要打样、要量产了才发现,同样写着“5557-2P”,有的厂报价几分钱… · 2026/9/27 10:56:46

Ubuntu 22.04 / 24.04 / 26.04 更换国内阿里源完整教程(区分 DEB822 新 / 旧源格式)
Ubuntu 22.04 / 24.04 / 26.04 更换国内阿里源完整教程(区分 DEB822 新 / 旧源格式)

前言随着 Ubuntu 版本迭代,APT 软件源配置分为两种格式:传统单行 sources.list 格式与全新 DEB822 标准格式,不同版本配置文件路径、写法完全不同,混用会直接报格式错误。Ubuntu22.04:仅使用 /etc/apt/sources.list 老… · 2026/9/27 10:56:46

源码+样机定制项目成本拆解:10万预算如何做不亏?
源码+样机定制项目成本拆解:10万预算如何做不亏?

前阵子接了个咨询,客户要做一套带硬件底座的智能设备,要求交付完整的源码加样机,对方预算卡在10万元。我帮他算了半天账,最后发现这事儿的利润空间远没有想象中那么乐观,但也不是完全没得做。今天把整个核算过程摊开来… · 2026/9/27 10:56:40

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码