Re: [bug-Class-DBI@xx.xxxx.xxx: [cpan #6434] LiveObject caching may return results from other DBs when using custom db_Main]
[prev]
[thread]
[next]
[Date index for 2004/05/28]
On Fri, May 28, 2004 at 06:48:46AM +0100, Tony Bowden wrote:
>
> My mod_perl2 application uses a custom db_Main method to connect to a database based on some information in the URL. The app may be called with, say, db=STORE_1 or db=STORE_2.
>
> The %Live_Objects caching introduced in CDB 0.96 uses the class name and primary keys to identify cached objects but does not pay attention to which DB instance the object belongs.
>
> Problem: In a persisted environment (mod_perl), if I retrieve an object with ID 123 from the STORE_1 database, it will be cached and subsequent queries for object with ID 123 in the STORE_2 database (or any other database accessed with this class) will return the cached object. This is incorrect behavior and a potential SECURITY HOLE since users of STORE_2 may now see data from STORE_1 without authorization.
>
> My Workaround: Use Class::CGI 0.95 which does not exhibit this problem.
>
> Solution: You should incorporate the dbh returned by $class->db_Main as part of the key used in identifying LiveObjects.
Using "$dbh" would be wrong. Using $dbh->{Name} would be better.
But even then there's a risk that multiple connections may use the
same DSN but different usernames (and thus different default schemas).
And even then there's a chance that connect() attributes may have a
significant influence on the connection.
I suggest moving the code that creates the $obj_key out into a
separate method that can then be subclassed in any way the application
may need. Document the issue alongside db_Main docs.
Here's an untested patch that also addresses [cpan #6435]
Tim.
--- DBI.pm.orig Fri May 28 10:06:28 2004
+++ DBI.pm Fri May 28 10:22:07 2004
@@ -509,19 +509,23 @@
my %Live_Objects;
my $Init_Count = 0;
+sub _live_object_key {
+ my ($class, $data) = @_;
+ my @primary_columns = $class->primary_columns;
+
+ # no key unless all PK columns are defined
+ return "" unless @primary_columns == grep defined, @{$data}{@primary_columns};
+
+ # create single unique key for this object
+ return join "\030", $class, map { $_ . "\032" . $data->{$_} }
+ sort @primary_columns;
+}
+
sub _init {
my $class = shift;
my $data = shift || {};
my $obj;
- my $obj_key = "";
-
- my @primary_columns = $class->primary_columns;
- if (@primary_columns == grep defined, @{$data}{@primary_columns}) {
-
- # create single unique key for this object
- $obj_key = join "|", $class, map { $_ . '=' . $data->{$_} }
- sort @primary_columns;
- }
+ my $obj_key = $class->_live_object_key($data);
unless (defined($obj = $Live_Objects{$obj_key})) {
|
|
Re: [bug-Class-DBI@xx.xxxx.xxx: [cpan #6434] LiveObject caching may return results from other DBs when using custom db_Main]
Tim Bunce 09:26 on 28 May 2004
|