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.

