小鹅通是知识付费圈子里跑得挺靠前的那批 SaaS,一堆课程、文档、直播都架在它上面。我不是专门来测的,就是下资料下累了,顺手把它的 H5 接口挨个点开扫了一遍,看正常的返回里会不会漏点东西出来。

漏的东西还真有,但都没啥技术含量,图一乐,记一笔。

参数没传,报错把结构体名抖出来了

GET /_alive/v3/get_lookback_url 这个接口,我故意把必填的 alive_id 空着不传,它直接原样甩回来一段:

1
{"code":422,"msg":"Key: 'LookBackRuleV2.AliveId' Error:Field validation for 'AliveId' failed on the 'required' tag"}

看一眼就知道后端是 Go(AliveId 这种驼峰命名太明显了),还顺便知道了内部结构体叫 LookBackRuleV2。参数校验失败,回一句通用的”参数有误”不就完了,非把结构体名字抖出来。

空文档一点,SQL 报错原样透出来

第二个在 POST /xe.course.business_go.goods.info.get/2.0.0。我拿一个没内容的文档资源去点,它回:

1
{"code":1,"msg":"get content info failed: SelectDocumentContent err:sql: no rows in result set"}

SelectDocumentContent 是内部的 SQL 函数名,no rows in result set 这种底层报错也没拦一下,直接透到前端。再配上刚才那个结构体名,数据库那边大概长什么样就能猜个大概了。这种报错老实写进服务端日志就得了,前端给句”暂无内容”就行。

直播服务的响应头里,写着自己的名字

这个不关接口的事,在域名上。直接打开 liveplay-byte.xiaoeknow.com 的根路径,回的是:

1
2
HTTP/1.0 400 Bad Request
Nss-Error: router.not.matched

NSS 是 NetStream Server,内部流媒体服务的代号。一个自定义响应头把内部服务名写在门牌上了,去掉也就几行代码。

文档链接,一点鉴权都没有

这个严格说不算漏洞,但我觉得是四个里最实在的一个。POST /xe.course.business.e_course.document_info.get/1.0.0 返回的 file_url 是 CDN 直链,指向 resource-tx-cdn.xiaoeeye.com,没有 token,也没有签名。直接 GET 那条链接,200,文件照样能下。

付费课程的文档链接只要漏出去,不管是被转发、截图,还是留在浏览器历史或者访问日志里,谁都能永久下载,还收不回来。对卖课的平台来说,这个可能比前面三个都更该先堵上。要么给下载加 CDN URL 鉴权和时效签名,要么走服务端中转。

顺带记一眼认证模型

扫接口的时候还摸到了这套平台认证的样子,也记一笔:

  • 会话认证用 Cookie ko_token,32 位 hex。
  • 视频回放走腾讯云点播的签名 URL,字段是 sign、t、us,sign 是 32 位 hex,看着像 MD5,强度没验。

收个尾

这几个洞没一个能直接打穿,说低危也不冤。有点意思的就是,几个接口的正常返回摆一块,后端长什么样就差不多拼出来了。至于怎么修,参数校验回通用错误、SQL 报错只进日志、响应头去掉内部标识,都是顺手的事。文档鉴权另说,得单独弄。

已经发到 security@xiaoe-tech.com 了。