/

CVE-2026-63221

Severity:

CRITICAL RISK

(9.4)

SQL Injection (CWE-89) in CodeIgniter deleteBatch

CVE-2026-63221

Received

Vulnerability type

Category:

SQL Injection

CWE:

CWE-89

Impact:

Arbitrary SQL Execution / Data Compromise

Severity:

CRITICAL RISK

(9.4)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

A SQL injection vulnerability in CodeIgniter's Query Builder deleteBatch() causes bound values from where() conditions to be interpolated into generated SQL without honoring their escape flags.

When user-controlled values are used in these where() conditions, attackers may inject arbitrary SQL, potentially leading to data exfiltration, modification, or deletion.

Affected context

This vulnerability arises in applications using CodeIgniter 4.3.0 through 4.7.3 that rely on the Query Builder's deleteBatch() API while passing user-influenced data into where() conditions.

It specifically affects the deleteBatch() code path, where bound parameters are substituted into the SQL string without respecting the configured escape behavior.

Regular delete() operations, which correctly escape binds, are not impacted.

Exploit preconditions

  • Attack surface: HTTP endpoints or APIs that trigger deleteBatch() with where() conditions derived from client input.
  • Required access: Ability to control or influence values passed into where() clauses used with deleteBatch().
  • Trigger point: Execution of deleteBatch() on a Query Builder instance that has where() conditions with untrusted values.
  • Why exploitation is possible: The deleteBatch() implementation injects bound values directly into SQL, ignoring escape flags, allowing crafted input to be interpreted as SQL rather than as data.

Why this happens

The core issue is an inconsistent parameter handling path within the Query Builder's deleteBatch() implementation.

While the general delete() method correctly escapes or parameterizes bound values according to their escape flags, deleteBatch() reconstructs SQL statements by directly substituting user-derived values without honoring those escape settings.

This pattern maps to CWE-89: Improper Neutralization of Special Elements used in an SQL Command, where untrusted input is concatenated into SQL text, allowing the database to interpret attacker-controlled input as part of the query.

Potential impact

  • Attackers may execute arbitrary SQL statements within the database context.
  • Application data can be read, modified, or deleted without authorization.
  • Logical integrity of tables may be compromised (e.g., mass deletions or targeted tampering).
  • Secondary security controls relying on database consistency can be undermined.
  • In some deployments, chained exploits may lead to broader system compromise.

General mitigation guidance

Mitigation focuses on ensuring that all delete operations use properly parameterized queries and that untrusted data is never concatenated directly into SQL.

Recommended patterns include:

  • Preferring Query Builder paths that consistently honor parameter escaping and binding semantics.
  • Validating and constraining user inputs before they are used to build where() conditions, particularly for identifiers, IDs, and dynamic filters.
  • Isolating and refactoring code that calls deleteBatch() so that it uses safer data access abstractions or alternative deletion mechanisms that enforce parameterization.
  • Applying least-privilege database roles so that even if an injection occurs, the impact is limited to the minimal necessary operations.
  • Centralizing data access logic to make it easier to enforce uniform query construction and escaping rules.

How teams detect issues like this

Detection can combine code-centric and behavior-centric approaches:

  • Static analysis: Search for usages of deleteBatch() where where() conditions are built from request parameters, query strings, or other untrusted sources; flag cases where values are not strongly validated or constrained.
  • Code review: During reviews, treat all deleteBatch() usage as high-risk and verify that inputs are either constant, server-derived, or safely parameterized; look for manual string concatenation or dynamic SQL fragments.
  • Runtime monitoring: Use database or application logs to flag anomalous delete patterns, unusual WHERE clauses, or errors indicative of malformed SQL.
  • Policy enforcement: Introduce coding guidelines that discourage or restrict direct use of high-risk query-building functions in favor of safer data access layers, and enforce these through automated checks in CI pipelines.

Sources

SourceLink
github.comgithub.com/codeigniter4/CodeIgniter4/commit/f5e463b9a3e986389ce285963e51a7f1fab6559f
github.comgithub.com/codeigniter4/CodeIgniter4/releases/tag/v4.7.4
github.comgithub.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-c9w5-rwh3-7pm9

Frequently asked

questions

Yes, if application endpoints accept user input that flows into where() conditions used with deleteBatch(), a remote attacker can exploit it via crafted HTTP requests.

An attacker needs the ability to influence the data used in Query Builder where() conditions for deleteBatch(), typically through standard web forms, query parameters, or API payloads; no administrative privileges are required if those endpoints are publicly reachable.

The safest pattern is to ensure that all deletion logic uses parameterized queries that respect escaping rules, refactoring deleteBatch() usage to safer alternatives or abstractions, and centralizing data access so all queries are constructed through vetted utility functions.

Prevent similar issues by standardizing on safe query-building patterns, enforcing strict input validation, using static analysis and code review checklists to flag direct SQL concatenation, and embedding security testing into the CI/CD pipeline to catch injection risks early.

Find out what's already
exploitable in your codebase.