views:

933

answers:

5

Obviously if I am using JDBC/ODBC, I can use bind variables and prepared statements to prevent SQL injection. However, when data is passed to batch processes that end up invoking Oracle SQLPlus, is there a way to prevent SQL injection? For example:

query.sql:

select '&1' from dual;
exit;

If I call this script from SQLPlus thusly:

$ sqlplus SCOTT/TIGER @query.sql "x','y"

I will get the following output:

old   1: select '&1' from dual
new   1: select 'x','y' from dual

' '
- -
x y

As you can see, SQLPlus command line parameters are using simple macro substitution. Is there an alternative method that I am missing? Otherwise, how do I prevent this from being exploitable?

A: 

You can't really have SQL injection attacks unless you're to expose your SQL*Plus scripts to malicious strangers on the internet. People who would actually attack your company.

It appears you're talking about batch jobs run in-house; entirely behind the fire wall, where the rest of the networks users are your co-workers, correct?

Unless they're seriously crazy sociopaths, "attack" doesn't have any meaning. Any SQL Injection problems that did arise would be either really abysmally bad design or reason for termination. That's just ordinary management of people's access and their skills in using the available tools.


Edit

While I can't pretend to know what "breakage due to control characters" means, I can provide some additional advice.

If you're suspicious that you may have a programming problem that -- via SQL injection -- will cause breakage at run-time, you need a test environment.

Clone your production schema to make a test schema. Load with a known subset of data. Run your SQL scripts on the test schema. If you have "somehow" put "control characters" into your SQL script, you'll have a test script that demonstrates this.

S.Lott
We do various data manipulations on customer data, but for cost and maintenance reasons we try to keep our asynchronous processing business logic out of the database. It's infinitely easier and more portable to version control and schedule stuff using cron/sqlplus than Oracle jobs/stored procedures.
DevelopersDevelopersDevelopers
I should have mentioned that this is as much about breakage due to control characters as it is about attack.
DevelopersDevelopersDevelopers
I'm sorry, I meant programmatically significant characters, from the user input, successfully loaded into a database, that is subsequently used to generate output. For example, an essay question that will be on a generated PDF. How do I pass a string of 250 characters of user data to SQLPlus safely?
DevelopersDevelopersDevelopers
At that point, you should get a better scripting environment than SQL-plus. It's not the injection "Attacks" -- there are none -- it's the inconvenience factor. Python plus mxOracle is still scripted, but a LOT easier to live with.
S.Lott
A: 

I would recommend using bind variables instead. In your script you should be able to do the following:

variable my_var varchar2(100);
begin
:my_var := &1;
end;
/
select :my_var from dual;

The "my_var" variable will be bound to the query. Instead of a simple find/replace.

Nick
+1  A: 

Passing parameters through SQL*Plus through the command line will be open to more than just SQL injection, as the command line will be interpreted through the OS first. So you also need to consider what the OS user might be able to do.

Personally, I'd ditch SQL*Plus and go with something like Perl. You have a proper programming language to wrap your SQL statements in, with much better handling of variables and exceptions.

Gary
+1  A: 

If people have sql*plus access to your database and you have the user id and password of a privileged user out here in a script for them to read, then you've just dropped your pants to them anyway. SQL injection is the least of your worries.

David Aldridge
A: 

You can user the following SQL Plus command: SET DEFINE OFF

Mohammad Makahleh