阿里云函数计算JS后端沙盒
本文纯属实验性质,如果有误请各位大佬指正。因使用本文所述的方法和技术所产生的安全风险,本文作者概不负责。
与上一篇介绍的前端沙盒相比,后端沙盒更加复杂而困难,安全风险也更高。当我们需要在服务端执行不受信任的动态代码时,往往我们需要限制代码对各种后端核心资源的访问权限,也需要限制执行代码的时间和空间。传统的方法通常是使用docker等隔离容器执行不受信任的代码,例如算法竞赛在线测评等,以此来实现对计算资源的精确控制和度量。
在本文中,我们介绍一种基于阿里云函数计算的JS后端沙盒。相比于传统的容器沙盒,函数计算沙盒更加简单容易,对于使用阿里云服务的应用平台也更加契合。
云函数
在阿里云函数计算服务中,创建一个新的服务和新的函数,选择基于事件的函数,不配置任何权限,不设置任何触发器。
这样,当前函数就不具有阿里云账户的任何权限,在其中也无法访问任何受保护的资源。因为没有触发器,所以此函数仅可通过SDK触发,我们就可以在上层应用中控制执行。
您还可以通过配置函数的超时时间和内存大小来限制函数的执行能力。安全起见,请不要配置并发。
沙盒代码
在新创建的函数中写入以下代码:
const AsyncFunction = (async function () {}).constructor
exports.handler = async (event, context, callback) => {
try {
const payload = JSON.parse(event.toString())
if (!payload.code) throw 'No Code'
const f = new AsyncFunction('ctx', payload.code)
const res = await f(payload.ctx)
callback(null, { ok: 1, res })
} catch (e) { callback(null, { ok: 0, err: e.toString() }) }
}
此事件函数接受一个JSON字符串,描述一个执行请求,包含一个代码字符串event.code
和一个可以在代码中使用的参数对象event.ctx
。通过创建AsyncFunction
的方式实现动态代码执行,代码中可以使用await
。
调用执行
使用阿里云函数计算官方SDK github.com/aliyun/fc-n…
npm i @alicloud/fc2
在代码中,使用阿里云的账户密钥调用函数,并传入事件参数:
const FCClient = require('@alicloud/fc2')
const client = new FCClient('<account id>', {
accessKeyID: '<access key id>',
accessKeySecret: '<access key secret>',
region: 'cn-shanghai'
})
// call function
resp = await client.invokeFunction(serviceName, funcName, JSON.stringify({
code: 'return ctx.a + ctx.b',
ctx: { a: 1, b: 2 }
}))
转载自:https://juejin.cn/post/7145901682449186830