views:

1340

answers:

1

I'd like to know if it's possible to execute more than one SQL statement within a single execute() or do() call using DBD::Oracle via Perl DBI. Example:

# Multiple SQL statements in a single query, separated by a ";"
$sql = 'UPDATE foo SET bar = 123; DELETE FROM foo WHERE baz = 456';

$sth = $dbh->prepare($sql);
$sth->execute;

# ...or...

$dbh->do($sql);

I ask this not because I want to actually do such a thing, but rather because I want to gauge the damage possible through a successful SQL injection attack. And yes, I know that, regardless of the answer to this question, the possibility of SQL injection must still be eliminated at its root using bind values and trusted input only, etc. But the question still stands: is it possible to make DBD::Oracle execute multiple statements?

As a related example, DBD::mysql has a mysql_multi_statements connection option that explicitly enables this "feature." I can't shake the feeling that there's some similar, perhaps undocumented and obscure Oracle OCI option that's accessible somehow via DBD::Oracle that will enable the same thing.

In case it matters, this is:

  • perl 5.8.8
  • DBD::Oracle 1.22
  • Oracle 11g (11.01.0700)
+5  A: 

If there is a successful SQL injection attack, couldn't the attacker simply repeat it and run multiple statements that way as well?

Oracle supports anonymous PL/SQL blocks which can contain multiple statements.

"begin execute immediate 'drop table customers'; execute immediate 'drop table sales'; end"

Oracle provides a free tutorial on avoiding SQL injection attacks here: http://st-curriculum.oracle.com/tutorial/SQLInjection/index.htm

Plasmer
The "begin execute immediate ..." technique did the trick. Thanks!
John Siracusa
I'm still curious about an injection into the middle of a statement, e.g. "SELECT foo FROM bar WHERE baz = '$x'" where $x is "123'; DROP TABLE abc" Does the "begin execute immediate" technique always require control of the statement from the beginning?
John Siracusa
Typically the "BEGIN" needs to be at the start of the statement, but there's probably a way around it. Depending on the packages your database user has access to, they could call packages like utl_http or utl_file and do bad things.
Plasmer