views:

119

answers:

6

I've got a string containing an SQL statement. I want to find out whether the query will modify data or database structure, or if it will only read data. Is there some way to do this?

More info: In our application we need to let the users enter SQL-queries, mainly as part of the applications report system. These SQL queries should be allowed to read whatever they like from the databse, but they shouldn't be allowed to modify anything. No updates, deletes insert, table drops, constraint removals etc.

As of now I only test whether the first word in the string is "select", but this is too constricting and too insecure.

+10  A: 

You should grant only select privileges on your tables for the login used by the application to be sure.

Pratik
No can do. The application needs to change data.
Svein Bringsli
@Svein Bringsli: Could you run the user-supplied queries with a different login? (btw you're directly contradicting your own question here, care to explain? "needs to change data" vs "shouldn't be allowed to modify anything")
Piskvor
@Svein Bringsli - Is it not possible to have a separate login just to execute the dynamic reporting queries and have that login with only SELECT privileges as per Pratik's suggestion? I do think that is the only really foolproof option here and having a separate login just for this dynamic reporting seems like an acceptable tradeoff, atleast to me
InSane
@InSane: Why is it not possible?
Billy ONeal
@InSane: You probably wanted a question mark there: "Is it not possible...?" - without the `?`, it may *seem* you're asserting "it is not possible".
Piskvor
@Piskvor + @InSane: That's what I get for trying to read with glasses off. +1 to the original comment :)
Billy ONeal
@InSane: A seperate login would probably be a good idea. I've never thought along those lines.
Svein Bringsli
+8  A: 

Create a new user for that part of the application that only has select privileges. Bear in mind that you'll also need to create synonyms for all the tables/views that that "read-only" user will be able to view.

The "regular" part of your application will still be able to do other operations (insert, update, delete). Just the reporting will use the read-only user.

As Horacio suggests, it is also a good idea/practice to add "wrapper" views that only expose what you want to expose. Some sort of "public API". This can give you flexibility if you need to change the underlying tables and don't want to/can't change the reports to the new definitions of said tables. This might, however, be seen as a lot of "extra work".

iggymoran
Why do I have to create synonyms for table/views? The "read-only-user" should be able to view the entire database, will that make a difference?
Svein Bringsli
If you don't create public synonyms then the readonly user has to use schemaname.tablename always where schemaname is the schema to which the tables belong. I think you should read a bit on Oracle.
Pratik
+3  A: 

I agree with others that the right thing to do is use a separate schema with limited access & privileges for those queries that should be read-only.

Another option, however, is to set the transaction read-only before executing the statement entered by the user (SET TRANSACTION READ ONLY).

Dave Costa
+2  A: 

Create VIEWS to expose the data to end users, this is worthy because of three things:

  1. The end user doesn't know how really your database look like.
  2. You may can provide a simpler way to extract some pieces of data.
  3. You can create the view with a read-only constraint:
    CREATE VIEW items (name, price, tax)
          AS SELECT name, price, tax_rate
          FROM item
          WITH READ ONLY;
Horacio Nuñez
+1  A: 

Something that has worked well for me in the past, but may not fit your situation:

  • Use stored procedures to implement an API for the application. All modifications are done via that API. The procedures exposed to the front end are all complete units of work, and those procedures are responsible for rights enforcement.
  • The users running the front end application are only allowed to call the API stored procedures and read data.
  • Since the exposed API does complete units of work that correspond to actions the user could take via the GUI, letting them run the procedures directly doesn't get them any additional ability, nor allow them to corrupt the database accidently.
Shannon Severance
+1  A: 

SELECT * FROM table FOR UPDATE works even with only SELECT privilege, and can still cause a lot of damage. If you want to be safe, the read only transactions are better.

Gary