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

CVE-2026-33639: InvoicePlane SQL Injection Vulnerability

CVE-2026-33639 is a SQL injection flaw in InvoicePlane that allows administrators to inject malicious SQL through schema-altering statements, corrupting database structures. This post covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-33639 Overview

CVE-2026-33639 is a SQL injection vulnerability in InvoicePlane, a self-hosted open source application for managing invoices, clients, and payments. Versions prior to 1.7.2 interpolate the administrator-controlled tax_rate_decimal_places setting directly into an ALTER TABLE statement for the ip_tax_rates table inside Settings::index() without strict integer validation. An authenticated administrator can craft a value that appends additional clauses to the schema-changing statement. The injected Data Definition Language (DDL) can remove or alter required database columns, corrupting financial data structures and rendering the application unavailable. The issue is tracked as [CWE-89] and is fixed in InvoicePlane 1.7.2.

Critical Impact

Successful exploitation permanently corrupts the InvoicePlane database schema, destroying financial data integrity and causing a sustained denial of service.

Affected Products

  • InvoicePlane versions prior to 1.7.2
  • Self-hosted InvoicePlane deployments exposing the Settings interface
  • Any installation with administrator accounts reachable over the network

Discovery Timeline

  • 2026-09-25 - CVE-2026-33639 published to NVD
  • 2026-09-29 - Last updated in NVD database

Technical Details for CVE-2026-33639

Vulnerability Analysis

The vulnerability resides in the InvoicePlane settings controller. When an administrator submits a new value for tax_rate_decimal_places, the application compares it with the stored setting and, if different, executes an ALTER TABLE statement against ip_tax_rates to resize the tax_rate_percent column. The decimal places value is interpolated into the raw SQL string using PHP string substitution. Because the input is never cast to an integer or bounded by range checks, any string the administrator submits reaches the database engine as DDL. An attacker who has acquired or already possesses administrator credentials can append statements that drop columns, rename fields, or otherwise alter the schema.

Root Cause

The root cause is improper neutralization of special elements used in an SQL command [CWE-89]. The setting value flows from the HTTP request into $this->db->query() without validation. CodeIgniter's Query Builder does not support DDL, so the code uses direct query execution, which places the responsibility for sanitization on the developer. That sanitization was absent prior to version 1.7.2.

Attack Vector

Exploitation requires an authenticated session with administrator privileges and network access to the Settings page. The attacker submits a crafted tax_rate_decimal_places field through the standard settings form. Because the vulnerable path is a schema change rather than a data query, the impact is persistent and extends beyond a single request.

php
// Vulnerable pattern in application/modules/settings/controllers/Settings.php (pre-1.7.2)
if ($settings['tax_rate_decimal_places'] != get_setting('tax_rate_decimal_places')) {
    $this->db->query("
        ALTER TABLE `ip_tax_rates` CHANGE `tax_rate_percent` `tax_rate_percent`
        DECIMAL( 5, {$settings['tax_rate_decimal_places']} ) NOT null");
}

Source: InvoicePlane Commit efec2d2

Detection Methods for CVE-2026-33639

Indicators of Compromise

  • Unexpected ALTER TABLE or DROP statements in MySQL general or binary logs referencing ip_tax_rates.
  • Missing or renamed columns in the ip_tax_rates table compared with a known-good schema.
  • Application errors referencing undefined columns when loading invoices or tax configuration.
  • Settings audit entries showing non-numeric values submitted for tax_rate_decimal_places.

Detection Strategies

  • Enable the MySQL general query log temporarily and search for DDL statements originating from the InvoicePlane database user.
  • Compare the live schema of ip_tax_rates against the shipped schema in the InvoicePlane repository.
  • Monitor web server access logs for POST requests to /settings containing suspicious characters in the tax_rate_decimal_places parameter.

Monitoring Recommendations

  • Alert on any schema-changing statement executed by the application database account outside of planned upgrades.
  • Track administrator logins and settings modifications in a central log store for review.
  • Baseline normal values for the tax_rate_decimal_places setting and flag deviations beyond the 2–3 range.

How to Mitigate CVE-2026-33639

Immediate Actions Required

  • Upgrade all InvoicePlane deployments to version 1.7.2 or later.
  • Audit the ip_tax_rates schema and restore from backup if columns are missing or altered.
  • Rotate administrator credentials and review recent administrator activity.
  • Restrict network exposure of the Settings interface to trusted administrators only.

Patch Information

InvoicePlane 1.7.2 resolves the issue through two complementary changes. Commit efec2d2 casts the input to an integer and enforces the 2–3 range before building the ALTER TABLE query. Commit 8fe4175 introduces a dedicated TaxRateDecimalPlacesProcessor class that uses filter_var with FILTER_VALIDATE_INT and explicit min_range and max_range options. See the InvoicePlane Security Advisory GHSA-34g5-4hfc-g983 and InvoicePlane Release v1.7.2.

php
// Fixed pattern from commit efec2d2
if ($settings['tax_rate_decimal_places'] != get_setting('tax_rate_decimal_places')) {
    // Cast to integer to prevent SQL injection
    $decimal_places = (int) $settings['tax_rate_decimal_places'];

    // Validate range (2-3 decimal places)
    if ($decimal_places < 2 || $decimal_places > 3) {
        $this->session->set_flashdata('alert_error', trans('invalid_tax_rate_decimal_places'));
        redirect('settings');
    }

    $this->db->query("
        ALTER TABLE `ip_tax_rates` CHANGE `tax_rate_percent` `tax_rate_percent`
        DECIMAL( 5, {$decimal_places} ) NOT null");
}

Source: InvoicePlane Commit efec2d2

Workarounds

  • Limit administrative access to InvoicePlane using IP allow-listing or VPN gating until the upgrade is complete.
  • Grant the InvoicePlane database user only the privileges required at runtime and remove ALTER outside of upgrade windows.
  • Take a full database backup before applying any settings changes so that schema corruption can be reversed quickly.

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.