Security Advisories (6)
CVE-2026-15043 (2026-07-14)

DBI::SQL::Nano versions from 1.42 before 1.651 for Perl have inverted <= and >= SQL operators on text. DBI::SQL::Nano, DBI's built-in mini-SQL engine, evaluated WHERE predicates incorrectly in some cases. In the non-numeric string branch of the is_matched method, <= was evaluated using Perl's ge operator, and >= was evaluated using Perl's le operator. SQL::Nano is the fallback query engine for DBI's file-backed drivers (DBD::File, DBD::DBM, CSV-style drivers) whenever SQL::Statement is not installed, and is forced whenever DBI_SQL_NANO=1. Queries over such tables use these predicates directly. The impact depends on the context. Where an application relies on a WHERE clause to filter file-backed data for policy or authorization, an inverted <=/>= comparison silently returns the wrong rows.

CVE-2026-15392 (2026-07-14)

DBD::File versions before 1.651 for Perl do not ensure the table file is not a symlink to an untrusted location. The complete_table_name method builds the absolute table file path without checking whether the file is a symbolic link. A link inside the data directory can point to a table file at any path outside of the configured f_dir and f_dir_search directories. Callers of file-based drivers can read or write files outside of the data directory.

CVE-2026-60081 (2026-07-14)

DBI::ProfileData versions before 1.651 for Perl do not limit the path index. The path index column of profile dump files is used to allocate an array of data for the parser. An unbounded value allows an attacker to specify a large index and consume available memory.

CVE-2026-60082 (2026-07-14)

DBI versions before 1.651 for Perl do not enforce statement handle consistency with the row. When the statement handle had no fields but the source row was non-empty, the internal row-buffer helper would read from a negative array index. This could be triggered by a caller supplying inconsistent metadata and rows to the prepare method.

CVE-2026-73193 (2026-08-15)

DBI versions before 1.652 for Perl allow a heap out-of-bounds write on 32-bit perl via an integer wraparound in the output buffer size computed by preparse. preparse reserves its output buffer with `newSV(strlen(statement) * 7 + 16)`, budgeting seven output bytes per input byte for the longest ':p99999' expansion. The product is computed in STRLEN, which is 32 bits wide on a 32-bit perl build, so a statement of 613,566,757 bytes multiplies to 4,294,967,299, wraps modulo 2^32 to 3, and reserves 19 bytes. The parser then copies the statement out through a raw pointer with no capacity check, writing the whole 585 MB input past the end of the allocation. The 99,999 placeholder limit does not bound this path, which is reached by ordinary non-placeholder content. Any caller that passes an untrusted statement of that length to preparse on a 32-bit perl gets a heap out-of-bounds write of attacker controlled bytes. Builds with a 64-bit STRLEN are not affected, since the wrap there needs a statement of about 2.3 exabytes.

CVE-2026-73194 (2026-08-15)

DBI versions before 1.652 for Perl allow a heap out-of-bounds write via an unvalidated numeric placeholder that sets the binder counter in preparse. preparse reserves seven output bytes per input byte, the width of the longest ':p99999' expansion. The ':N' branch parses the number with `atoi(src)` and assigns it to the binder counter with no range check, so a statement containing ':2147483648' leaves the counter negative (-2147483648 with glibc, where atoi wraps). Each following '?' then expands through `sprintf(start, ":p%d", idx++)` to ':p-2147483648', 14 bytes with the terminating NUL where the buffer budgets 7. The placeholder limit added in 1.650 tests the counter against 99,999, which a negative counter passes. Any caller that preparses an untrusted statement into ':pN' style placeholders gets a heap out-of-bounds write that grows with the number of '?' marks following the poisoned placeholder. The '?' and '%s' return styles compare the parsed number against the expected sequence and error out, and are unaffected.

NAME

DBD::Gofer::Transport::stream - DBD::Gofer transport for stdio streaming

SYNOPSIS

DBI->connect('dbi:Gofer:transport=stream;url=ssh:username@host.example.com;dsn=dbi:...',...)

or, enable by setting the DBI_AUTOPROXY environment variable:

export DBI_AUTOPROXY='dbi:Gofer:transport=stream;url=ssh:username@host.example.com'

DESCRIPTION

Without the url= parameter it launches a subprocess as

perl -MDBI::Gofer::Transport::stream -e run_stdio_hex

and feeds requests into it and reads responses from it. But that's not very useful.

With a url=ssh:username@host.example.com parameter it uses ssh to launch the subprocess on a remote system. That's much more useful!

It gives you secure remote access to DBI databases on any system you can login to. Using ssh also gives you optional compression and many other features (see the ssh manual for how to configure that and many other options via ~/.ssh/config file).

The actual command invoked is something like:

ssh -xq ssh:username@host.example.com bash -c $setup $run

where $run is the command shown above, and $command is

. .bash_profile 2>/dev/null || . .bash_login 2>/dev/null || . .profile 2>/dev/null; exec "$@"

which is trying (in a limited and fairly unportable way) to setup the environment (PATH, PERL5LIB etc) as it would be if you had logged in to that system.

The "perl" used in the command will default to the value of $^X when not using ssh. On most systems that's the full path to the perl that's currently executing.

PERSISTENCE

Currently gofer stream connections persist (remain connected) after all database handles have been disconnected. This makes later connections in the same process very fast.

Currently up to 5 different gofer stream connections (based on url) can persist. If more than 5 are in the cache when a new connection is made then the cache is cleared before adding the new connection. Simple but effective.

TO DO

Document go_perl attribute

Automatically reconnect (within reason) if there's a transport error.

Decide on default for persistent connection - on or off? limits? ttl?

AUTHOR

Tim Bunce, http://www.tim.bunce.name

LICENCE AND COPYRIGHT

Copyright (c) 2007, Tim Bunce, Ireland. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.

SEE ALSO

DBD::Gofer::Transport::Base

DBD::Gofer