Skip to main content
Vulnerability Database/CVE-2026-54790

CVE-2026-54790: InvoicePlane SQL Injection Vulnerability

CVE-2026-54790 is a second-order SQL injection flaw in InvoicePlane allowing attackers to query arbitrary schema data and cause denial of service. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-54790 Overview

InvoicePlane is a self-hosted open source application for managing invoices, clients, and payments. Versions prior to 1.7.2 contain a second-order SQL injection vulnerability [CWE-89] in the custom fields module. The application stores an administrator-controlled custom_field_table value without validating it against the allowed custom-field table names. The Mdl_custom_fields::used() method later concatenates that stored value into the FROM table and WHERE column identifier positions. Opening the custom-field edit form triggers execution of the injected SQL. The flaw is fixed in InvoicePlane 1.7.2.

Critical Impact

An authenticated administrator can inject SQL into identifier positions to query arbitrary schema data, trigger application errors, or cause denial of service.

Affected Products

  • InvoicePlane versions prior to 1.7.2
  • application/modules/custom_fields/models/Mdl_custom_fields.php
  • application/modules/custom_values/models/Mdl_custom_values.php

Discovery Timeline

  • 2026-09-25 - CVE-2026-54790 published to NVD
  • 2026-09-28 - Last updated in NVD database

Technical Details for CVE-2026-54790

Vulnerability Analysis

The vulnerability is a second-order SQL injection in the InvoicePlane custom fields subsystem. In a second-order injection, malicious input is first stored in the database, then executed when a later code path reads and uses the stored value in a query. Here, the custom_field_table form field is persisted without validation against the known set of custom-field table names.

When a user opens the custom-field edit form, Mdl_custom_fields::used() loads the stored custom_field_table value and concatenates it directly into the SQL query at identifier positions, both the FROM clause table name and the WHERE column name. Because these are identifiers rather than values, parameterized queries do not protect them, so the stored string is interpreted as SQL syntax.

An attacker able to submit the custom-field form can craft identifiers that pivot the executed query to read arbitrary schema or table data. Malformed identifiers also raise database errors that disrupt the custom-fields workflow, leading to application-level denial of service.

Root Cause

The root cause is missing allowlist validation on an identifier value sourced from user input and later used in dynamic SQL. The form validation rules required only that custom_field_table be present, not that it match one of the application's supported custom-field tables.

Attack Vector

Exploitation requires network access to the InvoicePlane application and an authenticated account with privileges to create or edit custom fields. The malicious payload is injected via the custom-field creation form and executed later when the edit form is loaded or when used() is invoked.

php
// Patch: application/modules/custom_fields/models/Mdl_custom_fields.php
'custom_field_table' => [
    'field' => 'custom_field_table',
    'label' => trans('table'),
-   'rules' => 'required',
+   'rules' => 'required|in_list[' . implode(',', array_keys($this->custom_tables())) . ']',
],
'custom_field_label' => [
    'field' => 'custom_field_label',

Source: InvoicePlane commit d3724169

The fix adds an in_list[...] validator so submitted values must match one of the keys returned by custom_tables(). A companion patch in Mdl_custom_values.php adds a defense-in-depth in_array check before using the stored identifier.

Detection Methods for CVE-2026-54790

Indicators of Compromise

  • Rows in the ip_custom_fields table where custom_field_table is not one of the application's known custom-field tables.
  • Database error entries in web server or PHP logs referencing Mdl_custom_fields::used() or malformed FROM clauses.
  • Unexpected information_schema queries originating from the InvoicePlane database user.

Detection Strategies

  • Audit the custom_fields table and flag any custom_field_table value outside the allowlist returned by custom_tables().
  • Review web access logs for POST requests to the custom-fields endpoints containing SQL syntax such as backticks, commas, or UNION keywords in the custom_field_table parameter.
  • Correlate administrator session activity with database errors emitted by the custom-fields module.

Monitoring Recommendations

  • Enable MySQL general query logging in staging to baseline queries emitted by Mdl_custom_fields::used() and alert on deviations.
  • Monitor privileged InvoicePlane accounts for anomalous custom-field creation or edit activity.
  • Forward application and database logs to a centralized analytics platform and alert on repeated SQL syntax errors from the InvoicePlane database user.

How to Mitigate CVE-2026-54790

Immediate Actions Required

  • Upgrade InvoicePlane to version 1.7.2 or later.
  • Audit existing ip_custom_fields rows and remove or correct entries where custom_field_table is outside the allowlist.
  • Restrict administrator access to the custom-fields module to a minimum set of trusted users.

Patch Information

The issue is fixed in InvoicePlane 1.7.2. The remediation adds an in_list[] form validator for custom_field_table and an additional in_array check in Mdl_custom_values.php before the identifier is used in a query. See the GitHub Security Advisory GHSA-vv4r-cgmw-w6x2, Pull Request #1573, and the v1.7.2 release notes.

Workarounds

  • If upgrading is not immediately possible, restrict access to the custom-fields administration pages via web server access controls.
  • Deploy a web application firewall rule to reject requests to custom-field endpoints where custom_field_table is not one of the allowed values.
  • Revoke unnecessary database privileges from the InvoicePlane database account to limit the data reachable through injected identifiers.
bash
# Example nginx rule to restrict access to the custom-fields module
location ~* ^/index\.php/custom_fields {
    allow 10.0.0.0/8;
    deny all;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.