New Attack Exploits "Safe" Oracle Inputs
Trailrunner7 writes "Database security super-genius David Litchfield has found a way to manipulate common Oracle data types, which were not thought to be exploitable, and inject arbitrary SQL commands. The new method shows that you can no longer assume any data types are safe from attacker input, regardless of their location or function. 'In conclusion, even those functions and procedures that don't take user input can be exploited if SYSDATE is used. The lesson here is always, always validate and prevent this type of vulnerability getting into your code. The second lesson is that no longer should DATE or NUMBER data types be considered as safe and not useful as injection vectors: as this paper (PDF) has proved, they are,' Litchfield writes."
Type safety and "safe" data types are two different things. One is a language construct intended to prevent errors in code through compile-time checking (though you pay in flexibility), the other is types of data that theoretically can be used in a database without doing validation checks.
I'll leave it as an exercise for you to figure out which one is which.
Javascript + Nintendo DSi = DSiCade
Yup. Basically, the only real way this could be exploited would be something like a stored procedure which takes one of the "vulnerable" types as parameters, exposed directly to the clients, and concatenate the types with little to no casting.
Something like (pseudocode, the following wouldn't even pass syntax check, obviously, but its stupid hard to find a working case)
DECLARE @blah SOMEVULNERABLETYPE
Exec "select * from stuff where stuff.Blah =" + @blah;
If @blah was a string, everyone would realise its vulnerable...but in this case, numbers, dates, etc, would be assumed safe (how do you put code in a number??), when it supposingly was discovered its not safe.
However, if you went through a database driver (not even an ORM!), and made a prepared statement, passed a Java (for example) variable as parameter to a query, well, no invalid input will be able to get through. If you add an ORM layer on top of that which does extra validation, then even if all of the types (both java and database) were vulnerable, it wouldn't go through either...
This is really more of a theoritical vulnerabilty than a real one... it can't realistically be exploited in the wild, and its hard to even -imagine- a scenario in a well coded app.
In this case setting NLS_DATE_FORMAT can be done by ANYONE regardless of whether they have ALTER SESSION granted.
some observations:
1. in most web apps you wont have access to the database, just the webserver...the database should be firewalled off.
2. it is RARE for PL/SQL developers to use resort to using dynamic SQL (execute immediate/DBMS_SQL) to run SQL, so this flaw, whilst interesting, is HIGHLY unlikely to be a problem...its certainly no where near as dangerous as developers not validating inputs where a application tier (java/php etc) does sql commands (esp if its not using bind variables) against a database [which by definition are dynamic sql calls].
Not to mention that using execute immediate without the USING clause and bind variables is again really rare by any half competent pl/sql developer.
3. the code also relies on another major error in the coding..type conversion. the date is implicitly converted to a string due to concatenation(||) i.e oracle rewrote that internally as to_char(v_date) and, as there was no supplied format it uses NLS_DATE_FORMAT.
i.e. in the example in the paper: stmt:='select object_name from all_objects where created = ''' || v_date || ''''; dbms_output.put_line(stmt); execute immediate stmt;
would undoutably be written PROPERLY as (in the dynamic case) execute immediate 'select object_name from all_objects where created = :b1' using v_date;
which is not susceptible to injection (NLS_DATE_FORMAT cant even come into play here).