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

CVE-2026-63221: CodeIgniter Query Builder SQLi Vulnerability

CVE-2026-63221 is an SQL injection flaw in CodeIgniter's Query Builder deleteBatch() method affecting versions 4.3.0 through 4.7.3. This article covers technical details, affected versions, security impact, and mitigation.

Published:

CVE-2026-63221 Overview

CVE-2026-63221 is a SQL injection vulnerability in CodeIgniter, a PHP full-stack web framework. Versions 4.3.0 through 4.7.3 are affected. The Query Builder deleteBatch() method substitutes bound values from where() conditions directly into the generated SQL string while ignoring the escape flags on those binds. User-controlled condition values can therefore be interpreted as SQL syntax rather than data. Only the deleteBatch() code path is affected; standard delete() operations escape where() binds correctly. The issue is fixed in CodeIgniter 4.7.4. The weakness is classified as [CWE-89] Improper Neutralization of Special Elements used in an SQL Command.

Critical Impact

Unauthenticated network attackers who can influence values passed to where() before a deleteBatch() call can inject arbitrary SQL, resulting in data tampering, mass deletion, or disclosure of database contents.

Affected Products

  • CodeIgniter4 versions 4.3.0 through 4.7.3
  • Applications using deleteBatch() in system/Database/BaseBuilder.php
  • Applications using deleteBatch() in system/Database/OCI8/Builder.php

Discovery Timeline

  • 2026-07-31 - CVE-2026-63221 published to NVD
  • 2026-07-31 - Last updated in NVD database

Technical Details for CVE-2026-63221

Vulnerability Analysis

CodeIgniter's Query Builder uses named binds such as :field: inside WHERE conditions. During normal delete() execution, the framework replaces those placeholders using parameterized queries or properly escaped literals. The deleteBatch() path takes a different route. It walks $this->QBWhere and rewrites each condition by calling str_replace() with the raw bind value, bypassing the per-bind escape flag stored alongside the value.

An application that passes user input into where() before invoking deleteBatch() allows that input to be concatenated directly into the compiled SQL statement. The database driver then parses the resulting string as executable SQL. Impact includes unauthorized deletion, modification, or exfiltration of records reachable by the current database user.

Root Cause

The defect is in the batch-delete SQL compilation logic. The pre-patch code iterated through $this->QBWhere and substituted $bind[0] (the raw value) while ignoring $bind[1] (the escape flag). This shortcut skipped the sanitization layer used by the standard delete pipeline.

Attack Vector

Exploitation requires that the application call deleteBatch() with where() conditions whose values originate from an untrusted source such as HTTP request parameters. No authentication or user interaction is required at the framework level; the attack surface depends on the application's exposed endpoints.

php
// Vulnerable pattern (pre-4.7.4): user input reaches where() before deleteBatch()
// The condition value is inlined into SQL without escaping.
            );

            // convert binds in where
-            foreach ($this->QBWhere as $key => $where) {
-                foreach ($this->binds as $field => $bind) {
-                    $this->QBWhere[$key]['condition'] = str_replace(':' . $field . ':', $bind[0], $where['condition']);
-                }
-            }
+            $this->convertWhereBindsForBatch();

            $sql .= ' ' . $this->compileWhereHaving('QBWhere');

Source: CodeIgniter4 commit f5e463b. The patch replaces the unsafe inline str_replace() loop with a new convertWhereBindsForBatch() helper that honors escape flags. The same change is applied to the OCI8 builder.

Detection Methods for CVE-2026-63221

Indicators of Compromise

  • Database logs containing anomalous SQL fragments such as stacked statements, UNION SELECT, or comment sequences (--, /*) inside DELETE queries generated by CodeIgniter.
  • Unexpected mass deletions or row counts in tables targeted by application deleteBatch() calls.
  • Web server access logs showing request parameters containing SQL metacharacters immediately preceding DELETE activity.

Detection Strategies

  • Perform static analysis of application code for invocations of deleteBatch() where where() arguments derive from $_GET, $_POST, JSON bodies, or other request-scoped inputs.
  • Enable database query logging and alert on DELETE statements whose WHERE clauses contain unquoted operators or nested SELECT fragments.
  • Deploy a web application firewall rule set that flags SQL injection payloads on endpoints known to execute batch deletions.

Monitoring Recommendations

  • Track the installed CodeIgniter version across managed applications and alert when any instance reports a version between 4.3.0 and 4.7.3.
  • Correlate application error logs with database driver errors that indicate malformed SQL, which often precede successful injection attempts.
  • Monitor outbound database traffic volume for spikes that could signal exfiltration through injected SELECT payloads.

How to Mitigate CVE-2026-63221

Immediate Actions Required

  • Upgrade CodeIgniter4 to version 4.7.4 or later on all affected applications.
  • Audit application code for use of deleteBatch() and confirm that inputs passed to where() are validated against an allowlist prior to the query.
  • Restrict database account privileges so that the application user cannot execute statements beyond those required by normal operation.

Patch Information

The fix is published in CodeIgniter4 release v4.7.4 and detailed in GitHub Security Advisory GHSA-c9w5-rwh3-7pm9. The patch introduces convertWhereBindsForBatch() in system/Database/BaseBuilder.php and system/Database/OCI8/Builder.php, replacing the unsafe substitution loop.

Workarounds

  • Replace deleteBatch() calls with the standard delete() method until the upgrade is applied, since delete() escapes where() binds correctly.
  • Cast or validate all condition values to strict types (for example integer IDs) before passing them to Query Builder methods.
  • Deploy WAF signatures that block SQL metacharacters on request parameters that feed batch-delete workflows.
bash
# Upgrade CodeIgniter4 to the patched release via Composer
composer require codeigniter4/framework:^4.7.4
composer update codeigniter4/framework
php spark --version

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

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

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.