本文探讨了微信小程序云函数中存在的功能越权漏洞,通过实例展示了未授权用户如何利用同一云函数执行增删改查等操作,强调了权限控制的重要性,并提出了功能拆分和最小权限原则的修复建议。
字数 1762,阅读大约需 9 分钟
前言
公司最近想把一部分业务迁移到云函数上。于是领导找到我,问我云函数可能存在哪些安全风险。
我两眼一抹黑,支支吾吾说我找找。
之前虽然了解过云函数,但那时候是搞云函数隐藏 C2 服务器的。我还真不知道,在业务上怎么处理。
正好趁这个机会学习一下,下面是最近的笔记。
环境搭建
大模型编程进步的速度令人吃惊,我直接注册了一个微信小程序,用大模型 + 腾讯云的 cloudbase 手搓了一个出来。
全程我只在给需求,几乎没有看过代码,遇到问题也是让大模型解决。最后,一天时间就把 demo 搓出来了。

云函数说明
因为是搭建的微信小程序,AI 编程工具CodeBuddy CN和腾讯云适配的很好,而且第一次用还给六个月免费。所以下面说的是腾讯云。

我的理解是云函数和微服务挺像的,微服务是把一个个功能点拆分到不同的服务器上。云函数也是把服务的功能点拆出来,换成函数的形式保存在云端。
使用的时候,通过固定的接口调用即可。
调用接口:
# 初始化
wx.init.cloud
# 调用
wx.cloud.callFunction

编译后测试
编译后用微信打开,按照开启微信小程序调试的办法打开
-
• https://github.com/evi0s/WMPFDebugger -
• https://github.com/JaveleyQAQ/WeChatOpenDevTools-Python
注意
我在测试的时候遇到了一个问题,就是微信魔改的浏览器,它在 appcontext 层级下,没办法显示响应包,也无法 console.log 打印。
微信 4.x 的解决办法是开启微信小程序的 vconsole 调试,因为我的小程序是开发版本,所以有这个按钮,但生产环境的没有,这就导致测生产会出现打印不了的情况。我看网上有用 jsrpc 调用 WebSocket,远程打印的。但我试了,没成功。
微信 3.x 的话,只要 WeChatOpenDevTools 开启调试即可。但需要绕过微信版本过低的问题,这个已有解决方法,可参考:https://bbs.kanxue.com/thread-289214.htm 或者 CE 改一个贼大的版本
开启调试后,全局搜索:wx.cloud.init
这里有对应的 cloudbase 的环境 env 值,这个值的话,需要和小程序的 wxid 对应才能使用。具体的校验机制没了解,不过也不影响。

wx 云函数调用
全局搜索 wx.cloud.callFunction

对应:

wx.cloud.callFunction({
name: "articleManager",
data: {
action: "getList",
data: {
page: n,
pageSize: o
}
}
原 JS 代码

简单
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const { action, data } = event
switch (action) {
case 'getList':
return await getArticleList(data)
case 'add':
return await addArticle(data)
case 'update':
return await updateArticle(data)
case 'delete':
return await deleteArticle(data)
default:
return {
code: -1,
message: '未知的操作类型'
}
}
}
断点调试

Network 中没有相关请求,这也是使用云函数的特点,没办法直接抓包

在微信开发者工具里,云函数是这样的

debug 状态下,wx.cloud 是有东西的

记得选择 appContext,在其他层级是没有wx的
写一个云函数调用代码:
wx.cloud.callFunction({
name: 'articleManager',
data: { action: 'getList', data: { page: 1, pageSize: 10 } }
}).then(res => console.log(res.result)).catch(err => console.error(err));
成功获取信息

漏洞分析
好了,看完上面的内容,请问改这个云函数调用过程有什么问题?存在什么漏洞?
答案是越权。毕竟文章标题就叫这个。
AI 想得比我全面,我只想要一个查看的功能,它很贴心的给我生成了articleManager,翻译过来是文章管理。
顾名思义,文章管理中不可能只存在查看,其他三个——增删改也跑不掉。一些开发在写代码的时候,也会多写几个对应的功能,便于未来扩展,但鉴权没做,图增攻击面。
AI 把增删改查写在了一个云函数当中,但并未对云函数本身进行权限限制,就导致了上述问题。
源码:

articleManager 中增加一篇文章的功能,代码如下:
// 调用添加文章的云函数用例
wx.cloud.callFunction({
name: 'articleManager',
// 传递给云函数的参数
data: {
// 对应云函数中处理添加文章的 action 标识(需与你的云函数路由逻辑匹配)
action: 'add',
// 要添加的文章数据,与 addArticle 函数接收的参数对应
data: {
title: '云开发入门教程', // 文章标题(必填)
link: 'https://example.com/cloud-guide', // 文章链接(必填)
author: '前端开发者', // 文章作者(必填)
tags: ['云函数', '小程序', '云开发'] // 文章标签(可选,不传则默认空数组)
}
}
})
.then(res => {
// 打印云函数返回的完整结果
console.log('添加文章结果:', res.result);
// 根据返回码判断是否添加成功
if (res.result.code === 0) {
wx.showToast({
title: '添加成功',
icon: 'success'
});
// 可获取新增文章的 ID(result.data 中包含 _id)
console.log('新增文章 ID:', res.result.data._id);
} else {
wx.showToast({
title: `添加失败:${res.result.message}`,
icon: 'none'
});
}
})
.catch(err => {
// 捕获调用云函数的网络/系统异常(非业务异常)
console.error('调用云函数失败:', err);
wx.showToast({
title: '调用接口失败',
icon: 'none'
});
});
console 中执行

查看我腾讯云中的云函数,可以看到成功添加进来了

同理,云函数 articleManager 下的删改也能使用
云函数

修复建议
云函数按照权限进行功能拆分,指定可以操作的角色。
未授权的用户只能使用查看的函数,授权的用户才能增删改。
在这里对云函数进行权限控制

下面的权限默认是所有云函数都可以访问
{
"*": {
"invoke": true
}
}
也就是说,虽然我们这里只有 articleManager,但是其他的云函数也是可以在其中调用的,只要 wxid 和云函数中的队友
比如 getTags
wx.cloud.callFunction({
name: 'getTags',
data: { event: '', data: { page: 1, pageSize: 10 } }
}).then(res => console.log(res.result)).catch(err => console.error(err));

如果贸然迁移功能到云函数,很可能就会出现越权的问题。
权限控制,在前后端分离的模式中都很难明确,在新的环境在更容易出问题。
不过,这也对我们测试的能力带来挑战。
总结
如果小程序使用了云函数,我们可以尝试在控制台中,检测云函数是否存在越权。新鲜事物,理解不当,就容易出现问题,安全人员对此态度应谨慎。
下面这篇文章,云函数也是出了类似的情况:
-
• 云函数开发的小程序的隐藏参数挖掘 https://mp.weixin.qq.com/s/vlzvLHg8b7-6oOssPa60Gw
对云函数写安全 checklist 和基线的时候,可以着重排查云函数中的功能拆分是否合理。以及给云函数配置的权限是否满足最小权限原则。
原文始发于微信公众号(进击的HACK):原创 | 小程序中云函数越权的探索
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-


评论