package MyApp::Schema::Result::Hash; use base qw/DBIx::Class::Core/; __PACKAGE__->table('hash'); __PACKAGE__->add_columns(qw/ key value /); __PACKAGE__->set_primary_key('key'); 1; package MyApp::Schema; use base qw/DBIx::Class::Schema/; __PACKAGE__->register_class(Hash => "MyApp::Schema::Result::Hash"); 1; package main; use warnings; use strict; use 5.010; use DBI; my $DB_FILE = "test.sqlite"; unlink $DB_FILE; my @DSN = ("dbi:SQLite:dbname=$DB_FILE","","", { AutoCommit => 1, RaiseError => 1 }); DBI->connect(@DSN)->do($_) for split /\n/, <<'INIT'; CREATE TABLE hash (key text, value text); INSERT INTO hash VALUES ('foo', 'FOO'); INSERT INTO hash VALUES ('bar', 'BAR'); INSERT INTO hash VALUES ('baz', 123); INIT #### my $schema = MyApp::Schema->connect(@DSN); my $hash = $schema->resultset("Hash"); my $good_key = "key"; say $hash->search({ $good_key => "foo" })->count; ## executes: SELECT COUNT( * ) FROM hash me WHERE ( key = ? ): 'foo' ## says 1 my $evil_key = "1 = 1 ) --"; say $hash->search({ $evil_key => "foo" })->count; ## executes: SELECT COUNT( * ) FROM hash me WHERE ( 1 = 1 ) -- = ? ): 'foo' ## says 3 #### $schema->storage->sql_maker->quote_char('"'); say $hash->search({ $evil_key => "foo" })->count; ## executes: SELECT COUNT( * ) FROM "hash" "me" WHERE ( "1 = 1 ) --" = ? ): 'foo' ## says 0 #### my $evil_key2 = 'key" = "key" ) -- '; say $hash->search({ $evil_key2 => "foo" })->count; ## executes: SELECT COUNT( * ) FROM "hash" "me" WHERE ( "key" = "key" ) -- " = ? ): 'foo' ## says 3 #### $schema->storage->sql_maker->quote_char(undef); my $Q_evil_key2 = $schema->storage->dbh->quote_identifier($evil_key2); say $hash->search({ $Q_evil_key2 => "foo" })->count; ## executes: SELECT COUNT( * ) FROM hash me WHERE ( "key"" = ""key"" ) -- " = ? ): 'foo' ## says 0