Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: December 10, 2007 - 8:58 pm UTC

Last updated: December 10, 2009 - 1:00 pm UTC

Version: 9208

Viewed 10K+ times! This question is

You Asked

Hello Sir,
How do I revoke access to dictionary Views from a particular schema.
I created a User and gave create session privilege only.
I use this user to execute a procedure which is owned by another user.

1)I need to revoke access from this user to all_tables , all_views etc etc which has PUBLIC access.
2)How to restrict this user only to let it execute the procedure given (which it has been granted execute privilege to) and do nothing else not even Selects.

Thanx

and Tom said...

1) well, that is not going to happen, they are granted to public and it would be very unwise to change that. Many undesirable side effects can and will result if you change the basic set of grants Oracle is expecting to be in place.

Besides - the dictionary only exposes objects that user is allowed to see, it is not a security issue.

2) That is not going to happen, it is not the way it works.



Why do you believe you need to do this (please do not respond with "my boss said so", I want to understand the logic behind this request so we can talk about why that logic is probably not relevant)

Rating

  (6 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Karthick Pattabiraman, March 17, 2008 - 5:38 am UTC

I assume from your comment that when a user is created by default he gets the access to all the required data dictionary tables. No explisit GRANT is made for that.
Tom Kyte
March 24, 2008 - 8:47 am UTC

every user has access to things that are granted to PUBLIC.

ops$tkyte%ORA10GR2> select * from dba_tab_privs where grantee = 'PUBLIC';

GRANTEE                        OWNER
------------------------------ ------------------------------
TABLE_NAME                     GRANTOR
------------------------------ ------------------------------
PRIVILEGE                                GRA HIE
---------------------------------------- --- ---
PUBLIC                         SYS
DUAL                           SYS
SELECT                                   YES NO

PUBLIC                         SYS
SYSTEM_PRIVILEGE_MAP           SYS
SELECT                                   YES NO
....




and the ALL_ USER_ views are granted to public.

ops$tkyte%ORA10GR2> select substr( table_name, 1, 4 ), count(*)
  2  from dba_tab_privs
  3  where substr( table_name, 1, 4 ) in ( 'ALL_', 'USER' )
  4  group by substr( table_name, 1, 4 );

SUBS   COUNT(*)
---- ----------
ALL_        329
USER        376


revoking PUBLIC access from ALL_ views

Chris Gould, December 01, 2009 - 11:21 am UTC

Tom -
one of our production DBAs has just built a new database on which we're going to be storing credit card details and thus has to meet the security criteria of the "Payment Card Industry" (PCI).
One of the things he's done to "secure" the database is revoke PUBLIC access from the ALL_ views.

He cites the following websites (none of them official Oracle sites) as his guides for this action, and also claims these sites ".. are the industry standards for securing Oracle".
http://www.cisecurity.org/bench_oracle.html
http://www.sans.org/score/oraclechecklist.php
http://iase.disa.mil/stigs/stig/index.html
www.petefinnigan.com

Is there any justification in what he's done? I think that fiddling around like this is a recipe for disaster.

Tom Kyte
December 01, 2009 - 12:16 pm UTC

bad idea, not very useful either. It is not going to hide anything that someone has access to anyway really.

can you be more specific, I don't want to read entire sites to find a reference, can you get them (your dba) to provide the citation whereby these sites say "this is a good idea (tm)"?


in the sans.org checklist, I see lots of questionable things - however, they say revoke select on all_users (ok with that), but then just say "secure all_% views", they do not say which ones or how - that is useless.

some things from sans site...

information on native compilation is dated.

information in utl_file is way dated.

suggestion to remove tkprof is silly, "it reads tracefiles" - so what? so does vi, should we remove vi? The goal would be to secure access the tracefiles, tkprof without tracefiles is just - well - nothing.


among others.





Bah

A reader, December 01, 2009 - 3:48 pm UTC

I've been through PCI data security requirements for our company. It is ludicrously complex and will require far more than just obscuring views.

We have come to the decision that we simply will not be storing credit card info. My hunch is that is exactly how they want you to respond.

the justification

Chris Gould, December 02, 2009 - 7:41 am UTC

Tom - thanks for your earlier reply.

Our dba has provided the following quote from one of the documents as his justification for revoking public access to the ALL_ views :
As an example, the ALL_USERS view is accessible to PUBLIC and it lists the username of every database schema. A technique often used by hackers is to obtain and use a list of valid user accounts to try to access those accounts. Privileged database option schemas (such as MDYS), default application accounts, and user accounts will be listed by the ALL_USERS view as valid targets to a nefarious user. The list of valid database users then becomes a list of valid database targets. A malicious user could easily say, “Oh look, the <insert option name or your application here> is installed. Let me use the default password and try to access this privileged account.” 
Therefore, you should consider revoking PUBLIC access to certain database metadata. Looking at SYS objects that start with ALL is a good place to start: 

He's clearly interpreted the last couple of sentences as meaning revoke public access from everything prefixed ALL.
I've passed your earlier comments on to him.
Tom Kyte
December 04, 2009 - 8:06 am UTC

and if you hide all_users, I'll just select distinct owner from all_objects. Take away all_objects and I'll just use

ops$tkyte%ORA11GR1> select table_name from all_tab_columns where column_name = 'OWNER' and table_name like 'ALL\_%' escape '\';

TABLE_NAME
------------------------------
ALL_SDO_MAPS
ALL_SDO_GEOM_METADATA
ALL_SDO_THEMES
...
ALL_LOG_GROUP_COLUMNS
ALL_PLSQL_OBJECT_SETTINGS
ALL_CUBE_VIEWS

243 rows selected.


mdsys is well known, I don't really need all_users. I wouldn't even bother to look to see if it where there to try and access it.

And beside, if you try the default password and it works - all_users or not - the dba hasn't done the most basic of things (lock down the accounts).

Meaning - using any of the usual accounts with the tag line "A malicious user could easily say, “Oh look,
the <insert option name or your application here> is installed. Let me use the
default password and try to access this privileged account.” " doesn't make you look very good - does it? I mean, who in their right mind would go production with something like that.

And access to all_users wouldn't prevent anyone from trying anyway. I never look to see if CTXSYS exists before trying to log on as CTXSYS, I just do it.

Goal

Rob Scalzo, December 05, 2009 - 6:37 pm UTC

I can see where the recommendation is trying to get to though. Say you had an app connecting in that turned out to be vulnerable to SQL Injection. Yep it’s a bad app that needs fixing but these things seem to raise their head all too frequently.

If the app connects using a separate user from the schema holding your data (as it should) then the default grants of the ALL views to PUBLIC makes it real easy for the attacker to get a good idea of your data model and what privileges the application has on the tables.

Your right though, ALL_USERS by itself it isn’t enough, as your examples show it would need a revoke of most of the ALL views, USER_TAB_PRIVS_RECD as well (and maybe others) to get to a point where someone exploiting a SQL injection loophole is left sitting there scratching their head trying to randomly guess what the schema holding your data is called and what you’ve named your tables.

I wonder if Oracle has ever considered some form of fine-grained revocation, something where if something is granted to PUBLIC it could be revoked for a particular user (a revoke getting stored and overriding the grant rather than just removing a grant as happens as it is), that way you could lock down the application login accounts with a lot more control.

Leaving technology aside though I suspect as with all these things it’s pushed by the external regulators in whatever industry your business happens to be in and ends up being a box-ticking exercise, the regulators want you to prove that you’ve hardened your dbs in order to be compliant. They need some way of standardising and measuring that so they just say implement SANS, CIS or <flavour of the month>...

SQL injection attack

Chris Gould, December 08, 2009 - 9:34 am UTC

In the case of my database though, I use 3 separate accounts : one for the PL/SQL packages, one for the tables and one for the application connection. The app-connection account only has access to the packages; it has no grants on any of the tables. Therefore anyone connecting as the app-conn account would see nothing in the ALL_% views relating to the database tables. Surely this would therefore make it unnecessary to revoke public access from the ALL_% views?

Tom Kyte
December 10, 2009 - 1:00 pm UTC

do you use dynamic sql?
do your clients bind to your plsql routines?

if the answer is

no, i do not use dynamic sql in my plsql.
yes, my clients NEVER pass literals in their plsql blocks, they ALWAYS use binds.


then you are not subject to sql injection. sql injection can only happen in PL/SQL with dynamic sql - it is IMPOSSIBLE to sql inject a plsql routine that uses static sql.

and as long as your clients always use blocks of code like:

'begin procedure( :x, :y, :z ); end;'

and never do something like:


'begin procedure( ''' || variable || ''', ..... '

the clients are not subject to sql injection.



but I don't think this conversation is centered around sql injection - the theory here is "someone has gained access to my database using some account and would like to use that account to 'probe' the database for more information"



You had better make darn sure the clients that use your single set of code never ever use concatenation to invoke you - since they have access to ALL OF your code (single account), they can run anything and they probably look at who is connected and only let them run certain things. If they do that, you better not ever use string concatenation lest someone figure out how to get around it by faking you out.



More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library