Executing User-Supplied Queries with DBMS_SQL
The DBMS_SQL default package allows SQL to be dynamically executed. Owned by SYS it has been defined with the AUTHID CURRENT_USER keyword so it runs with the privileges of the invoker. This protects the DBMS_SQL procedures against direct attacks, but if called from another PL/SQL program that uses definer rights it can be problematic. Before we get to how the DBMS_SQL procedures can be dangerous, let's examine how it works. Consider the following code:
DECLARE C NUMBER; R NUMBER; STMT VARCHAR2(200); BEGIN STMT:='SELECT 1 FROM DUAL'; C :=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(C, STMT, DBMS_SQL.NATIVE); R := DBMS_SQL.EXECUTE_AND_FETCH(C); DBMS_SQL.CLOSE_CURSOR(C); END;
Here a cursor, C, is opened using the OPEN_CURSOR function. The SQL statement, ‘SELECT 1 FROM DUAL’, is then parsed using DBMS_SQL.PARSE(C, STMT, DBMS_SQL.NATIVE). Once parsed, the query is executed using DBMS_SQL.EXECUTE_AND_FETCH(C). Alternatively, the DBMS_SQL.EXECUTE(C) function could be called followed by a call to DBMS_SQL.FETCH_ROWS(C). Finally, the cursor is closed with DBMS_SQL.CLOSE_CURSOR(C). Any query can be executed by these procedures. This includes calls to GRANT, CREATE, and ALTER. When an attempt is made to run such a query using DBMS_SQL, however, an error is returned.
ORA-01003: no statement parsed ORA-06512: at "SYS.DBMS_SYS_SQL", line 1216 ORA-06512: at "SYS.DBMS_SQL", line 334
It has, however, succeeded. To see this in action, run the following queries: ...
Get The Database Hacker's Handbook: Defending Database Servers now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.