ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

消除 `@platejs/media` 中的 js-video-url-parser ReDoS 漏洞:从依赖清理到自研解析器的安全修复实践

消除 `@platejs/media` 中的 js-video-url-parser ReDoS 漏洞:从依赖清理到自研解析器的安全修复实践 消除platejs/media中的 js-video-url-parser ReDoS 漏洞从依赖清理到自研解析器的安全修复实践【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本文以 plate 仓库中 2026-04-24-js-video-url-parser-redos.md 修复计划与 安全解决方案记录 为主线完整复盘一次真实的第三方依赖 ReDoS正则表达式拒绝服务漏洞处置如何识别js-video-url-parser的 CVE-2026-5986 暴露面、用URLAPI 自研解析器替换依赖、用计时回归测试锁定性能、以及通过 changeset 与自动发布工作流完成发布闭环。读完本文你将掌握一套可复用的“依赖 CVE 修复方法论”并能在platejs/media中自行验证 YouTube / Vimeo / Dailymotion / Youku / Coub 五种平台的视频链接解析行为。背景媒体嵌入功能与 ReDoS 攻击面platejs/media是 plate 富文本编辑器生态中的媒体插件包package.json。它负责把用户粘贴或输入的原始链接如 YouTube、Vimeo 视频地址解析为统一的嵌入数据再插入编辑器的 mediaEmbed 节点。解析入口是 parseVideoUrl.ts 导出的parseVideoUrl它被 insertMediaEmbed.ts 与 submitFloatingMedia.ts 通过urlParsers机制组合调用。问题出在该解析器历史上依赖第三方包js-video-url-parser。该包被安全公告 CVE-2026-5986 标记为存在 ReDoS 漏洞其getTime相关的时间参数正则解析在遭遇精心构造的输入时会发生灾难性回溯导致解析线程长时间阻塞。在本仓库中pnpm-lock.yaml曾锁定js-video-url-parser0.5.1packages/media/package.json也直接声明了该依赖两个位置共同构成了发布包的漏洞暴露面。ReDoS 的实际表现修复计划中记录了漏洞的实证复现方式复现命令bun test packages/media/src/lib/media-embed/parseVideoUrl.spec.ts针对一个25 位非法t参数值的输入解析耗时约360ms后失败恶意输入形如https://www.youtube.com/watch?vM7lc1UVf-VEt111...111x——一段超长数字串后跟一个不匹配的x正是触发正则回溯的经典载荷安全扫描器会同时报告js-video-url-parser0.5.1同时出现在package.json与pnpm-lock.yaml。对于服务端渲染或 AI 批量处理场景这种毫秒级停滞可被放大为拒绝服务因此该问题被评级为 medium 严重度见解决方案文档的 frontmatter。为什么“升级版本”与“局部加固”都行不通修复计划明确排除了两条看似省事的路径这对任何依赖 CVE 处置都有参考价值版本升级不可行当时已知受影响版本覆盖0.5.0与0.5.1在公告语境下不存在可安全升级的目标版本也就是“没有 safe bump target”仅在 Plate 调用点加固不够即便在parseVideoUrl外层做输入校验或降级处理被公告标记的漏洞依赖仍留在已发布包的依赖图package graph中扫描器依然会告警。因此结论是持久性修复必须移除依赖并把 Plate 真正需要的这一小片解析逻辑收归自有代码。这既是安全修复也是一次“控制面收敛”——第三方包为通用场景提供了大量本仓库用不到的元数据与时间解析能力而这些能力恰恰是攻击面所在。解决方案用 URL API 自建零正则解析器修复的核心思路在 parseVideoUrl.ts 中落地放弃正则驱动的字符串匹配改用标准URLAPI 少量确定性字符级校验函数。整个文件不引入任何正则表达式。解析主流程const parseUrl (url: string) { if (!isUrl(url)) return; try { return new URL(url); } catch { return; } };parseUrl先用platejs导出的isUrl做协议/形态粗校验再用new URL(url)完成标准化解析非法 URL 会抛异常并被捕获返回undefined。主函数parseVideoUrl随后遍历内置的提供商常量表逐个尝试解析export const parseVideoUrl (url: string): EmbedUrlData | undefined { const parsedUrl parseUrl(url); if (!parsedUrl) return; for (const provider of VIDEO_PROVIDER_VALUES) { const id parsersprovider; if (!id) continue; const embedUrl ${providerUrls[provider]}${id}; return { id, provider, sourceKind: url, sourceUrl: embedUrl url ? undefined : url, url: embedUrl, }; } };返回的EmbedUrlData结构定义在 parseMediaUrl.ts包含id、provider、sourceKind、sourceUrl、url五个字段。值得注意的是当输入 URL 本身就是官方 embed 地址如https://player.vimeo.com/video/97276391时embedUrl url此时sourceUrl会被置为undefined避免冗余存储。该结构随后还会经过 parseMediaUrl.ts 的二次加固只放行http:/https:协议其余协议一律丢弃以防御 XSS。防 ReDoS 的字符级校验工具真正消除灾难性回溯的是下面这套基于字符码的判断函数全部为线性扫描无正则、无回溯isAlphaNumeric(value)逐字符检查是否为0-9、A-Z、a-zisNumeric(value)逐字符检查是否为0-9isYoutubeId(value)要求长度严格为 11且仅含-、_或字母数字stripNonAlphaNumericSuffix(value)找到第一个非字母数字字符的位置并截断其后内容用于处理 Dailymotion/Youku 链接末尾的标题后缀。这些工具函数的时间复杂度均为 O(n)与输入长度线性相关从根本上不存在正则引擎的指数级回溯路径。五家平台的 ID 提取策略平台支持的 host 形态ID 提取来源YouTubeyoutu.be、youtube.com、*.youtube.com?v/?ci查询参数路径中embed、v、vi、videos、shorts、live段之后的位置Vimeovimeo.com、*.vimeo.com、vimeopro.com、*.vimeopro.com路径中从后向前找到的第一个纯数字段Dailymotiondai.ly、dailymotion.com、*.dailymotion.comdai.ly取首段其余取video段之后的位置并截掉非字母数字后缀Youkuyouku.com、*.youku.comVideoIDS查询参数路径中embed、sid段或以id_开头的段截掉.html等后缀Coubcoub.com、*.coub.comview或embed段之后的位置解析得到的 embed 前缀常量同样定义在 parseVideoUrl.tsYouTube 为https://www.youtube.com/embed/Vimeo 为https://player.vimeo.com/video/Dailymotion 为https://www.dailymotion.com/embed/video/Coub 为https://coub.com/embed/Youku 为https://player.youku.com/embed/。测试策略供应商变体 计时回归双保险修复计划强调“在删除解析器依赖之前先用测试保住公共 helper 行为”并专门克隆了上游jsVideoUrlParser仓库交叉核对 provider 变体。落地后的测试文件是 parseVideoUrl.spec.ts其测试矩阵分为四层1. 主 URL 与变体 URLYouTube 主 URLhttps://www.youtube.com/watch?vM7lc1UVf-VEYouTube 变体youtu.be短链、m.youtube.com/details?v、/embed/路径、/v/路径、gdata.youtube.com/feeds/api/videos/路径Vimeo 主 URL 与变体/channels/staffpicks/、/album/2903155/video/、/groups/shortfilms/videos/、/showcase/12345/video/、vimeopro.com/staff/frame/video/以及“已是 embed 地址时sourceUrl应为undefined”的断言。2. 非 YouTube 平台Dailymotion/video/x7tgcz与带_后缀标题的/video/x1e2b95_bruce-lee-nin-kayip-kedisi_animals、短链dai.ly/x1e2b95Youkuv.youku.com/v_show/id_XMzI1NjYxNTI.html需去掉.html、player.youku.com/player.php/sid/XMTQ3OTM4MzMxMg/v.swf、static.youku.com/...?VideoIDS...%3D%3D查询参数需 URL 解码Coubcoub.com/view/abc123与coub.com/embed/by7smembed 形态sourceUrl为undefined。3. ReDoS 计时回归核心it(does not backtrack on invalid time parameters, () { const url https://www.youtube.com/watch?vM7lc1UVf-VEt${1.repeat(25)}x; const start performance.now(); expect(parseVideoUrl(url)).toEqual({ id: M7lc1UVf-VE, provider: youtube, sourceKind: url, sourceUrl: url, url: https://www.youtube.com/embed/M7lc1UVf-VE, }); expect(performance.now() - start).toBeLessThan(100); });这条用例直接复刻漏洞载荷25 位数字 非法x断言两件事一是解析结果不受影响t参数被忽略、ID 仍正确提取二是整体耗时必须小于 100ms——与此前 ~360ms 的失败表现形成对照。它保证了未来任何重新引入正则解析的改动都会被 CI 立即拦住。4. 边界输入parseVideoUrl(not a url)返回undefined。发布链路changeset 自动合并 Release PR由于platejs/media是已发布包本次修复涉及“包输出或用户可见依赖变化”因此必须走 changeset 流程运行pnpm install后pnpm-lock.yaml中的js-video-url-parser0.5.1被移除新增 changeset 文件本仓库 changeset 使用方式见 .changeset/README.md记录版本变更意图执行完整验证链bun test packages/media/src/lib/media-embed/parseVideoUrl.spec.ts→pnpm turbo build --filter./packages/media→pnpm turbo typecheck --filter./packages/media→pnpm lint:fix→pnpm check。修复计划还提到一处自动化增强为 changeset PR 增加“自动发布”勾选项。其设计为——PR 正文带一个受管理的复选框release 工作流读取已合并PR 的复选框状态若为勾选则对生成的[Release] Version packagesPR 启用 auto-merge。配套增加了检测 changeset PR、保留受管复选框状态、忽略受管块之外零散复选框文本的共享辅助函数并新增changeset-auto-release工作流以在 changeset PR 上持续保留该复选框同时更新release.yml读取合并 PR 的勾选结果。相关验证包括bun test tooling/scripts/auto-release-pr.test.mjs、node --check、git diff --check、YAML 解析与pnpm check。可复用的 ReDoS 依赖修复清单综合本次修复的完整过程可以沉淀出如下适用于任何 npm 包的处置流程定位暴露面确认漏洞包同时出现在package.json直接依赖与锁文件传递依赖的哪些位置评估受影响版本范围复现攻击形状构造触发正则回溯的最小载荷用计时测试如performance.now()量化延迟作为修复前后的对照基线评估升级可行性若受影响范围覆盖当前锁定版本且无安全替代版本果断放弃“升版本”路线移除依赖并自建最小实现只保留业务真正需要的解析面优先用标准库如URLAPI替代正则字符级线性扫描替代复杂匹配用测试锁行为迁移上游测试用例覆盖各 provider 变体并为 ReDoS 形状专门添加计时回归断言清理锁文件执行pnpm install或对应包管理器让锁文件摘除漏洞包确保发布图干净走发布流程通过 changeset 记录版本变更完成 build、typecheck、lint 全量验证后合入如有自动发布需求可在 changeset PR 中启用受管理的自动合并复选框。这套方法不仅适用于js-video-url-parser对任何“正则驱动的第三方解析器 CVE 公告”组合都同样成立——把攻击面从不可控的第三方正则引擎收回到可控、可测、可审计的自有代码中。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表