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

CVE-2026-13766: DBIx::QuickORM SQL Injection Vulnerability

CVE-2026-13766 is a SQL injection flaw in DBIx::QuickORM for Perl that allows attackers to inject malicious SQL through unquoted identifiers. This article covers technical details, affected versions, and mitigation steps.

Published:

CVE-2026-13766 Overview

CVE-2026-13766 is a SQL injection vulnerability in the Perl module DBIx::QuickORM for versions before 0.000026. The default SQL builder subclasses SQL::Abstract and sets bindtype in its constructor but never sets quote_char. As a result, SQL::Abstract emits caller-supplied identifiers verbatim into generated SQL. Attackers who influence identifier positions such as order_by values, where-clause column keys, field and returning lists, upsert columns, or join aliases can inject arbitrary SQL. The weakness is classified under CWE-89.

Critical Impact

Untrusted input reaching any identifier slot enables data disclosure via sub-selects and tampering through crafted where and update identifiers.

Affected Products

  • DBIx::QuickORM for Perl, all versions before 0.000026
  • Applications using the default DBIx::QuickORM::SQLBuilder::SQLAbstract builder
  • Perl services forwarding user input to identifier positions such as order_by, field, or returning

Discovery Timeline

  • 2026-06-30 - CVE CVE-2026-13766 published to NVD
  • 2026-06-30 - Last updated in NVD database

Technical Details for CVE-2026-13766

Vulnerability Analysis

The vulnerability stems from missing identifier quoting in the ORM's SQL generator. DBIx::QuickORM::SQLBuilder::SQLAbstract instantiates SQL::Abstract without a quote_char. Under this configuration, SQL::Abstract inserts identifiers into the generated statement without any wrapping quotes or escaping. The ORM's field_db_name() helper also passes unknown names through unchanged, compounding the exposure.

Values remain safe because they are bound as placeholders. Identifiers are not. Caller-supplied strings reach the SQL string raw at multiple positions: order_by, where-clause column keys, field and returning lists, upsert columns, and join aliases. An attacker who controls any of these can terminate the identifier context and append arbitrary SQL clauses.

Root Cause

The constructor in lib/DBIx/QuickORM/Connection.pm created the builder with only bindtype configured. Without quote_char, SQL::Abstract treats identifier arguments as trusted literal SQL fragments, violating the separation between SQL structure and untrusted input required by [CWE-89].

Attack Vector

A typical attack forwards untrusted input to an identifier position. For example, a user-controlled order_by value can be crafted so that row ordering depends on a sub-select over columns the query never selected, leaking data through timing or observable ordering. Where-clause and update identifier positions permit further disclosure and record tampering.

text
# Security patch entry from Changes
+    Security:
+    - Quote all SQL identifiers so caller-supplied names (order_by, where keys,
+      field/returning lists, upsert columns, and join aliases) can no longer
+      break out into SQL injection (CVE-2026-13766).
+
+    INCOMPATIBLE CHANGES (from the CVE-2026-13766 fix):
+    - SQL identifiers are now quoted, changing two caller-facing behaviors:
+      - order_by/field bare strings must be column names, not raw SQL.
+      - A bare "name DESC" or "COUNT(*)" no longer works; use \'...' or {-desc => 'name'}.
+      - LiteralSource croaks on a non-identifier 'subquery' alias.

Source: GitHub Patch Commit

Detection Methods for CVE-2026-13766

Indicators of Compromise

  • Database query logs containing unexpected sub-selects appearing inside ORDER BY clauses generated by DBIx::QuickORM.
  • Application logs showing user-supplied strings such as column names containing spaces, parentheses, commas, or SQL keywords reaching ORM identifier arguments.
  • Anomalous UPDATE or SELECT statements with unusual identifier fragments emitted by Perl services using DBIx::QuickORM prior to 0.000026.

Detection Strategies

  • Enable database statement logging and grep for identifiers that contain whitespace, --, /*, or nested SELECT inside identifier positions.
  • Perform source code review for calls that pass request parameters into order_by, field, returning, where keys, upsert columns, or join aliases.
  • Inventory Perl dependencies using cpanm --info DBIx::QuickORM or META.json scanning to identify installations older than 0.000026.

Monitoring Recommendations

  • Alert on database errors mentioning unknown columns or syntax errors originating from ORM-generated queries, which often accompany injection probing.
  • Monitor for spikes in query duration on endpoints that accept sorting or column selection parameters.
  • Correlate web access logs containing suspicious sort parameters with corresponding backend SQL statements.

How to Mitigate CVE-2026-13766

Immediate Actions Required

  • Upgrade DBIx::QuickORM to version 0.000026 or later on all affected Perl systems.
  • Audit application code for any path that forwards untrusted input into identifier arguments and restrict values to a strict allowlist.
  • Review historical database logs for signs of prior exploitation attempts against identifier positions.

Patch Information

The fix is committed as 43d7684682050780f056f25e1879191fb0a3265e and shipped in release 0.000026. The patch instantiates SQL::Abstract with a quote_char derived from the live DBI driver (SQL_IDENTIFIER_QUOTE_CHAR, DBI get_info(29)) and sets name_sep => '.'. When the driver returns nothing usable, the ANSI double-quote is used as a fallback. Note the incompatible change: bare strings like "name DESC" or "COUNT(*)" in order_by or field no longer work and must be expressed with \'...' or {-desc => 'name'}. See the MetaCPAN Release Changes and the OpenWall OSS Security Discussion.

Workarounds

  • Constrain caller-supplied identifiers with a server-side allowlist mapping user tokens to known column names before passing them to the ORM.
  • Reject any order_by, field, or where key input containing characters outside [A-Za-z0-9_].
  • If upgrading is not immediate, subclass the SQL builder to pass an explicit quote_char matching the target database dialect.
perl
# Interim mitigation: force identifier quoting when constructing the builder
require DBIx::QuickORM::SQLBuilder::SQLAbstract;
my $qc = eval { $dbh->get_info(29) };
$qc = '"' unless defined($qc) && $qc =~ /\S/;
my $builder = DBIx::QuickORM::SQLBuilder::SQLAbstract->new(
    quote_char => $qc,
    name_sep   => '.',
);

Source: GitHub Patch Commit

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.