OSV 1.4.0 · github-reviewed · 修改于 2026-07-25 05:17
发布时间
2026-07-25 05:17
GitHub 审查时间
2026-07-25 05:17
NVD 发布时间
—
源文件
advisories/github-reviewed/2026/07/GHSA-xcx6-4f2g-hhgx/GHSA-xcx6-4f2g-hhgx.json
In Budibase v3.39.4, a regression in the authorization level for the S3 attachment upload endpoint allows any BASIC app user to obtain S3 PutObject presigned URLs. The endpoint uses TABLE/WRITE permission level instead of the intended BUILDER level defined in v3.39.3. Additionally, the controller does not pin the target bucket to the datasource's configured bucket, allowing writes to any S3 bucket the stored IAM credentials can access.
POST /api/attachments/<datasourceId>/url
Content-Type: application/json
x-budibase-app-id: <appId>
{"bucket": "target-bucket", "key": "malicious-file.html"}
The /api/attachments/:datasourceId/url route was changed from authorized(BUILDER) in v3.39.3 to authorized(PermissionType.TABLE, PermissionLevel.WRITE) in v3.39.4. BASIC users have TABLE/WRITE permissions by default, so they can call this endpoint. The controller at packages/server/src/api/controllers/static/index.ts:614-632 accepts the bucket parameter directly from the request body and passes it to getSignedUrl without validating against the datasource's configured bucket.
The test suite at packages/server/src/api/routes/tests/static.spec.ts:218-235 confirms this behavior. The test authenticates as a BASIC role user and successfully generates a signed upload URL, verifying HTTP 200 and a defined res.body.signedUrl.
authorized(BUILDER) middleware on the routeparamResource("datasourceId") to ensure the datasource belongs to the caller's appdatasource.config.bucket in the controller, ignoring the caller-supplied bucket value