已发布 Budibase 工作区中低权限(BASIC 角色)的已认证用户可以调用 POST /api/attachments/:datasourceId/url,并获得一个使用工作区数据源的服务端 AWS 凭据签名的 S3 预签名上传 URL,适用于攻击者控制的对象键(并且,如果数据源没有固定存储桶,也可以是攻击者控制的存储桶)。
| CVE | CVE-2026-54356 |
| 公告 | GHSA-6x9p-4r67-5gjx |
| 软件包 | @budibase/server |
| 类型 | CWE-862:缺少授权 |
| 受影响版本 | < 3.41.3 |
| 修复版本 | 3.41.3 |
| 严重性 | 高 — CVSS 3.1 7.1(AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N) |
| 所需权限 | 已认证的 BASIC 应用用户 |
packages/server/src/api/routes/static.ts:
.post(
"/api/attachments/:datasourceId/url",
recaptcha,
authorized(PermissionType.TABLE, PermissionLevel.WRITE), // too low, wrong resource
controller.getSignedUploadURL
)
packages/server/src/api/controllers/static/index.ts(getSignedUploadURL)通过 :datasourceId 加载数据源,取出其存储的 accessKeyId/secretAccessKey,并为攻击者提供的 bucket/key 签署 PutObject 请求:
const { bucket, key } = ctx.request.body || {}
const s3 = new S3({
credentials: {
accessKeyId: datasource?.config?.accessKeyId as string,
secretAccessKey: datasource?.config?.secretAccessKey as string,
},
})
signedUrl = await getSignedUrl(s3, new PutObjectCommand({ Bucket: bucket, Key: key }))
生成一个由凭据支持的签名 URL 属于特权操作,但该检查仅要求通用的表写入权限(BASIC 角色拥有该权限),并且从不验证调用者是否有权使用该特定数据源。预期结果:403。实际结果:返回 200 及 signedUrl/publicUrl。
PutObject 预签名 URL。curl/PUT)。参见 poc/:
poc/exploit.sh — curl PoC(登录 → 生成签名 URL → 上传证明文件)。poc/poc.py — 相同的流程,使用 Python 实现。python3 poc/poc.py \
--target http://localhost:10000 \
--app-id app_xxx --datasource-id datasource_xxx \
--email [email protected] --password 'Password123!' \
--bucket my-attachments --key poc/cve-2026-54356/proof.txt \
--upload
升级到 Budibase 3.41.3+。如果无法立即升级,请将 S3 数据源的 AWS 凭据范围限制为最小权限(存储桶/前缀受限的 IAM 策略),并监控意外的 PutObject 活动。
由 @KovachVL 发现并报告。
仅限教育/防御用途及协同披露。仅可测试您拥有或明确获授权测试的系统。