Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Issuing a DELETE statement with DBI

by mattdope (Acolyte)
on Sep 01, 2006 at 08:39 UTC ( [id://570739]=perlquestion: print w/replies, xml ) Need Help??

mattdope has asked for the wisdom of the Perl Monks concerning the following question:

hi there hope someone can help. I have and html form which is being posted to a cgi script. Whatever the user input's in the form should delete the correspoding row from the database. When I post my form, i get taken to the script and it there appear to be no errors. However, the row is not deleted from my database. I am using
//to get the value from the form my $testTitle = param('title'); //to delete the row in the database $rows = $dbh->do(" DELETE FROM music WHERE title = $testTitle ");
the page just says done at the bottom but no modification in database. Can anyone suggest a poss. reason for this?

2006-09-01 Retitled by Corion, as per Monastery guidelines
Original title: 'dbi-delete'

Replies are listed 'Best First'.
Re: Issuing a DELETE statement with DBI
by b10m (Vicar) on Sep 01, 2006 at 08:57 UTC

    First of all, you really really really want to use place holders for starters, to prevent SQL injection (also see a column on this by merlyn).

    And to be honest, I think that'd solve your quoting problem too (for I assume the lack of quotes around the $testTitle is giving your DB problems)

    (besides the commit answer, given by aquarium, of course).

    --
    b10m

    All code is usually tested, but rarely trusted.
      cheers mate will give that a try
Re: Issuing a DELETE statement with DBI
by bart (Canon) on Sep 01, 2006 at 11:53 UTC
    You have a value quoting/placeholder problem, which b10m already pointed out to you. But I'd like to show you how the code can look when using DBIx::Simple, which allows using methods coming from SQL::Abstract, and takes care of those issues all by itself:
    $db->delete('music', { title => param('title') });

    A really nice thing about SQL::Abstract and, thus, DBIx::Simple is that it takes care of the special case where the value is undef, for a field value of NULL, too. Just using placeholders wouldn't do, as the SQL query

    DELETE FROM music WHERE title = NULL
    won't ever delete anything.

      Be aware that directly using the results of the param function as key/value pairs for a hash opens up an interesting attack vector if you have more than one key/value pair. Assume the above code and the following query, which doubles the title parameter to whack the key/value pairing off by one, turning all subsequent keys into values and all subsequent values into keys:

      ?title=foo;title=user;bar=

      This would send off the following query instead:

      $db->delete('music', { title => 'foo', user => undef });

      In this specific case, the attack isn't effective obviously, as you can still only add more restrictions on what rows to delete, instead of widening the query. If the attacker can guess one of the parameters that need to be overridden, this still can be an effective attack:

      $db->insert('users', { is_admin => 0, user => param('username') });

      Here, the attacker can easily overwrite admin to any value they want by supplying an appropriately formatted query:

      ?user=corion;user=is_admin;user=1

      So, I think that one should never use the results of param() directly in another list that will get passed on without further scrunity. Note that no parameter validation that validates a single parameter will protect you against this vector.

        OK... So how about this?
        $db->delete('music', { title => scalar param('title') });
        I was curious about this, so I ran a quick test and was unable to duplicate your findings (CGI.pm version 3.05). In my output, the keys and values appear as I would expect. Can you please explain how you came to your conclusion? Here's my code:
        #!/usr/bin/perl use strict; use warnings; use CGI; my $cgi = CGI->new(); use Data::Dumper::Simple; print Dumper($cgi); print scalar $cgi->param('title'); print $/; __END__ > ./tmp.pl title=foo\;title=user\;bar= $cgi = bless( { '.parameters' => [ 'title', 'bar' ], 'bar' => [ '' ], '.charset' => 'ISO-8859-1', '.fieldnames' => {}, 'title' => [ 'foo', 'user' ], 'escape' => 1 }, 'CGI' ); foo
        Thanks!

        ---
        It's all fine and dandy until someone has to look at the code.
Re: Issuing a DELETE statement with DBI
by dokkeldepper (Friar) on Sep 01, 2006 at 10:51 UTC
    Hi,

    in some sense I just conclude the previous answers: The perlish part
    1. Don't use user inputs directly to modify a database Use tainted variables, arrange the input intelligently.
    The Database part:
    2. It seems, that you use one large table for your project. However, you should really do some normalization. For example, create tables for the Artists, CDs, Titles separately. At least you should try to separate the static part of your database from the changing part, or slowly changing parts from fast changing parts. For example, create a table for the users (it is relatively static) and a table for the comments or deleted titles (relatively dynamic).
    3. DELETE is on every serious RDBMS an operation that requires a COMMIT (sometimes this is done automatically) because it is an operation that can leave the database in an inconsistent state. May be, it is required here.
    4. If DELETE is done frequently, use prepared statements.
    These are some ideas for the moment. I hope these are useful for the further design.

Re: Issuing a DELETE statement with DBI
by aquarium (Curate) on Sep 01, 2006 at 08:53 UTC
    is this an Oracle or other such database that requires a "commit" for the transaction to be actually written?
    the hardest line to type correctly is: stty erase ^H

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://570739]
Approved by b10m
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2024-04-23 13:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found