Changes for version v1.1.0 - 2026-09-08

  • SECURITY
    • All dynamic class loading locations were secured to prevent code injection (CWE-94). The schema_class, result_class and similar specifications used to go through the eval "require $class" method which means that the code got executed in Perl and not only loaded as a module at 8 locations in the code. Any string that could be recognised as a class name combined with any number of ';' separated Perl instructions could cause arbitrary code execution while being loaded.
    • One of the paths of the 'result_class' resultset attribute in ResultSet::new_result was looked at in a proof of concept together with its unique accidental protection because of its protection clause, unless $target_class->can('can'), which gets true for any string that has ever existed (all classes inherit UNIVERSAL::can), therefore making the problematic line executing any code. The other call points are protected with different protection clauses (for example, ->can('connect')) and were confirmed to be affected.
    • The following new function has been added: DBIx::Class::Async::_safe_require_class. It checks the validity of the name of the class and then loads it using function require($file), providing a similar mechanism as Class::C3::Componentised::ensure_class_loaded. All calls to eval "require $class" and the double-interpolated eval "package main; ... " VERSION fallback function have now been changed to use this method. The previously ambiguous ->can('can') check has also been replaced by an actual check that the class was loaded before.
  • TEST SUITE
    • A new test file t/157-safe-class-loading.t has been created, and a regression check has been added to t/123-result-class.t file to make sure that any malicious schema_class/result_class strings are rejected and no code is being run when real classes are being processed.

Documentation

Modules

Non-blocking, multi-worker asynchronous wrapper for DBIx::Class
Base class for DBIx::Class::Async exceptions
Exception for column names that are ambiguous across joined tables
Translate raw DBIx::Class errors into typed exception objects
Exception for absent required columns on insert
Exception for undeclared relationship names used in queries
Exception for operations on un-inserted row objects
Exception for relationship name passed where a column was expected
Non-blocking resultset proxy with Future-based execution
Asynchronous pagination handling for Async ResultSets
Asynchronous operations on a single ResultSource column
Asynchronous Row object representing a single database record.
Non-blocking, worker-pool based Proxy for DBIx::Class::Schema
Normalise -ident clauses in ResultSet select attributes
Storage Layer for DBIx::Class::Async
DBI-based async storage backend for DBIx::Class::Async
Asynchronous cursor for DBIx::Class ResultSets using Futures