Oracle newly created user privileges issue? - database

Does newly created user:
create user John
identified by secret;
have some privileges? Or is there any oracle config for privileges of newly created user? I need information about this topic.

Nope, no privileges.
select * from dba_sys_privs where grantee='JOHN';
select * from dba_tab_privs where grantee='JOHN';
select * from dba_role_privs where grantee='JOHN';

ammoQ is technically correct.
Given the user created as above does not have CREATE SESSION privilege, it cannot actually log on yet, or do anything else.
It is possible for another user with an appropriate CREATE ANY ... privilege to create objects (such as procedures, functions, triggers) under JOHN's schema/user. If so, then JOHN would automatically have privileges to drop those objects (but without a CREATE SESSION privilege, it would be difficult for them to achieve that).
From a security point of view, Oracle does have a bunch of privileges granted to PUBLIC. Once a user is created they do have a bunch of things they can do (eg select from views such as ALL_USERS).

Related

How to block other users from writing to my schema in Oracle

I need to create an user in Oracle (19c) that can only read and write to his own schema - the user cannot see any other schemas (except the default, system schemas).
Also, other users cannot be able to write (create) anything to that user's schema.
How can I achieve that?
That's the default state for a newly-created user - you'd have to grant privileges to allow the new user to see anything else, or for any other use to see the new user's objects (never mind create new ones).
So you don't need to do anything special - you just need to grant your new user the system privileges they need to connect to the database and create their own objects.
The exception is existing users with 'any' privileges, which usually only applies to DBAs. Or if grants to any other schema's objects have been made to the PUBLIC role, which is usually not done.
Read more about privileges.

Restricted PostgreSQL permissions for web app

Goal
Create a database with three users and restrict their privileges (I'm just thinking out loud, so my user separation is also open to correction):
Superuser - this user allows for the very initial provisioning of the database. Create the application database, create the other users, set their privileges. Default postgres superuser works for me, so this one is done.
Administrator - this user has access only to the database that was created during provisioning. Administrator can CRUD all data in all tables, and can also CRUD tables, etc. "Superuser for only this database" type of situation. When the application is being updated, the administrator is the user used by automated tooling to handle database migrations.
App user - this user is ultimately the one who supports the web app's functionality. Note this has nothing to do with users on web pages etc - this is the user the server leverages to run queries, insert and remove data. I explicitly do not want this user to be able to modify permissions of anything, nor create/destroy tables or indices or anything structural.
What I've tried
First off, looking at the (generally excellent) PostgreSQL documentation, the page on Grant pretty much leaves me cross-eyed. After spending a few hours reading about PostgreSQL roles and privileges I'm generally confused. I think with a bit more work I'll be able to nail down what I want for the admin user, but I'm pretty stuck on the "app user". I've gotten about this far (naming and passwords are all just placeholders):
$ psql -U postgres
postgres=# CREATE USER "app-admin" WITH PASSWORD 'password';
CREATE ROLE
postgres=# CREATE USER "app-user" WITH PASSWORD 'password';
CREATE ROLE
postgres=# CREATE DATABASE "test-database" WITH OWNER "app-admin";
CREATE DATABASE
postgres=# \c "test-database"
You are now connected to database "test-database" as user "postgres".
test-database=# DROP SCHEMA "public";
DROP SCHEMA
test-database=# CREATE SCHEMA "app" AUTHORIZATION "app-admin";
CREATE SCHEMA
And here's where I get unsure. I feel like the answer I'm trying to avoid is "revoke everything by default then enumerate all the privileges you'll need at all the different levels on all the different objects". I'm trying to avoid that because I straight up don't know what I need there. If that ends up being the answer, then I'll just have to hunker down and read a bunch more, but generally when I start going down paths like that I've missed something.
Issues
How do I restrict privileges for app-user so they are unable to modify any structural data (e.g. cannot add or destroy tables) but are able to connect and do anything with rows (row level security is not even on my radar). Is this general model of privileges not really in sync with what PostgreSQL expects? I feel like I'm missing something if I have to walk through every option on that "grant" page to accomplish something like this - whether it be my motivation for doing it in the first place or the means by which I'm going about it.
Context
I'm trying to build my first end-to-end web application. I've done enough general software development and web app development, now I'm trying to understand the pieces that I generally take for granted day to day. I'm trying to set up a PostgreSQL server while keeping the principle of least privilege in mind.
Side-quest
I haven't seen this done on web apps where I have simply joined the development team, although they're generally small and not heavily used. Does doing this actually accomplish anything? Does anyone have compelling reasons for why to do something like this, or why it's a bad or ineffective idea? My assumption was that if I ultimately ended up with a SQL injection vulnerability, this would mitigate the damage because the database user would have limited access. Is that misguided?
Neat articles I've found on the subject:
http://www.ibm.com/developerworks/opensource/library/os-postgresecurity/index.html
PDF WARNING: https://wiki.postgresql.org/images/d/d1/Managing_rights_in_postgresql.pdf
https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2
http://blog.2ndquadrant.com/auditing-users-and-roles-in-postgresql/
I'll answer your “side-quest” question first:
you are completely right with your worries and concerns, and everybody who designs an application should think about the same things. Everything else is sloppy and careless.
To mitigate the damage that can be caused by a successful SQL injection attack, you should definitely employ the principle of least privilege.
It should be quite simple to set up a system that matches your requirements.
I'll use the object names from your exaple, except that I'll use underscores instead of minuses. It is good practive to use only lower case letters, underscores and numbers in object names, since it will make your life easier.
/* create the database */
\c postgres postgres
CREATE DATABASE test_database WITH OWNER app_admin;
\c test_database postgres
/* drop public schema; other, less invasive option is to
REVOKE ALL ON SCHEMA public FROM PUBLIC */
DROP SCHEMA public;
/* create an application schema */
CREATE SCHEMA app AUTHORIZATION app_admin;
/* further operations won't need superuser access */
\c test_database app_admin
/* allow app_user to access, but not create objects in the schema */
GRANT USAGE ON SCHEMA app TO app_user;
/* PUBLIC should not be allowed to execute functions created by app_admin */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin
REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
/* assuming that app_user should be allowed to do anything
with data in all tables in that schema, allow access for all
objects that app_admin will create there */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, USAGE ON SEQUENCES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT EXECUTE ON FUNCTIONS TO app_user;
But if you take the principle of least seriously, you should grant table permissions individually and e.g. not allow app_user to DELETE and UPDATE data in tables where there is no need for the user to do so.
For Web Applications, I split the permissions into three roles, where each role inherits from its predecessor.
Read Only - Used for SELECT queries and function calls
Insert - Used for INSERT statements
Update and Delete - These are used mostly for Administration, as the public facing front-end application does not usually modify or deletes data
That way, even if some hacker manages to do SQL Injection he is limited to the permissions of the role that is used, usually only SELECT or INSERT.
My web applications usually do not need the more intrusive permissions like CREATE, DROP, TRUNCATE, etc., so I don't GRANT those permissions to web apps.
In the rare instances where the the second role needs to update or delete something, I either give it permission for that specific table, or put the code in a function that is created with SECURITY DEFINER.
/** role_read is read-only with SELECT and EXECUTE */
CREATE ROLE role_read;
/** role_read_add adds INSERT */
CREATE ROLE role_read_add;
/** role_read_add_modify adds UPDATE and DELETE */
CREATE ROLE role_read_add_modify;
GRANT USAGE ON SCHEMA <schema> TO role_read;
/** for existing objects */
GRANT SELECT ON ALL TABLES IN SCHEMA <schema> TO role_read;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA <schema> TO role_read;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA <schema> TO role_read;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT SELECT ON TABLES TO role_read;
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT SELECT ON SEQUENCES TO role_read;
/** role_read_add inherits from role_read */
GRANT role_read TO role_read_add;
/** for existing objects */
GRANT INSERT ON ALL TABLES IN SCHEMA <schema> TO role_read_add;
GRANT ALL ON ALL SEQUENCES IN SCHEMA <schema> TO role_read;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT INSERT ON TABLES TO role_read_add;
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT ALL ON SEQUENCES TO role_read_add;
/** role_read_add_modify inherits from role_read_add */
GRANT role_read_add TO role_read_add_modify;
/** for existing objects */
GRANT UPDATE, DELETE ON ALL TABLES IN SCHEMA <schema>
TO role_read_add_modify;
/** for future objects */
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT UPDATE, DELETE ON TABLES TO role_read_add_modify;

Grant Object Privileges to users in SAP Hana

I need to grant object privileges to a user but I'm not the owner of the schema.
I've tried doing it with the System user but I can't either.
My long shot was using the Sys user (other than System) but it is deactivated and there is no way I'll be able to activate it with my user.
Is there any way I grant that privilege to a user? I can't ask the owner of the schema to do that because she resigned today... and I don't wanna change the pwd of her DB user.
I know that at some point I'll need to create a new DBAdmin user and create a backup of those schemas because when the SAP user of my colleague be deleted, it'll delete the Hana user and the DB user with all of the objects, roles and privileges created and granted with it.
Oh oh!
Be very careful here with the deletion of the user since - as you correctly write - the deletion will have a cascading effect.
Also:
you have to either have the ownership for the objects OR the privileges you want to grant with grant option.
Using the SYSTEM user won't help with that and SYS can never be used to logon to the database anyway.
Since there is also no way to take over ownership, the only actual way really is to find out which objects and privilege grants the user has created/performed.
Then logon to the user and refactor the grants to roles that cover the object privileges.
As a next step, you may consider creating a non-logon user to own the objects and then perform a import/export of the users' objects.
Finally you may create design time roles with the required privileges to the objects. This allows granting/revoking of the privileges by a user with the ROLE ADMIN privilege, which makes management a lot easier and better structured.
Sure:
(
SELECT "SCHEMA_NAME",
'' AS "OBJECT_NAME",
'SCHEMA' AS "OBJECT_TYPE", "SCHEMA_OWNER" as "OWNER_NAME"
FROM "PUBLIC"."SCHEMAS"
WHERE SCHEMA_OWNER = 'A' UNION ALL
SELECT "SCHEMA_NAME", "OBJECT_NAME",
"OBJECT_TYPE", "OWNER_NAME" FROM "PUBLIC"."OWNERSHIP"
WHERE
"SCHEMA_NAME" IN
( SELECT "SCHEMA_NAME" from "PUBLIC"."SCHEMAS"
WHERE "SCHEMA_OWNER" = 'A' ) OR "OWNER_NAME" = 'A'
) ORDER BY "SCHEMA_NAME" ASC, "OBJECT_NAME" ASC;
You find this and lots of other useful stuff in the SAP HANA book I wrote: https://www.sap-press.com/sap-hana-administration_3506/

set user's default database/schema in Sybase IQ

i googled it and find nothing. Short story, i created a user and granted to a table in my SyBase. but when i try
select * from table1
it didn't work. Error show Permission denied: you don't have permission to select from "table1" and i try add dbname before table name like this and it works :
select * from dbname.table1
i suspect that user default database is something else so i want to set dbname to his default database. Anyone know how to do this?
This has nothing to do with database names (or login policies). Given your comment that "dbname" is actually the user who owns the table, here's what's happening.
When you specify a table name without an owner, the server has to figure out which table you mean. It first looks for a table that you own with that name. If it doesn't find one, it looks for tables owned by any groups that you are a member of. I suspect that one of these groups has a table named "table1" that you do not have permission to select from.
When you specify a table name with an owner, the server knows exactly which table to use. Since you do have permission to select from that table, you get the results you want.
IQ doesn't have default databases/schemas. Instead it uses login policies. Each database has a login policy assigned to it, which can be altered. You can also create custom login policies.
When you create a user account with out specifying a login policy, it automatically gets the root login policy.
For more information, check the following SAP Sybase IQ docs:
Intro to IQ: Managing Users and Groups
System Admin Guide V1: Managing User IDs and Permissions
Using a view or procedure is a useful method. That said, to establish a "default" schema in (IQ 15.x) one would use groups. Essentially, one grants group to the schema owner and makes the individual login accounts (or other groups) members of that group. Note that this only gives the user access to the schema--that is, it eliminates the need to preface the object with the schema/owner name (unless there are object name conflicts only resolvable with explicit schema.object naming). This does not include a grant of permissions. None of the implicit table-owner related privileges will inherit. However, as the schema/owner is now also a group, permissions could be granted at that level.
See: http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc00170.1540/doc/html/san1288042708174.html (Managing User ID's and permissions). Be warned: this material generally requires some close reading and experimentation before it becomes useful.
As I understand it, this method is complementary to (functionally replaced by) the new role-based model in IQ 16. However, as I am still feeling my through IQ 16, there is probably a great deal more to be said, and I am not ready to comment just yet.

PostgreSQL - Securing DB and hide structure

I am deploying a database in postgreSQL and I created a user that just will be able to execute certain functions.
I revoked all privileges from the user i just created and granted connect privileges executing:
REVOKE ALL PRIVILEGES ON DATABASE <database> FROM my_user;
REVOKE ALL PRIVILEGES ON SCHEMA public TO my_user;
GRANT CONNECT ON DATABASE <database> TO my_user;
But when i connect to the database with this user, i am able to read all table structures and all function source codes. Is there a way to hide it from this user?
I take the chance to make another question: I want to just execute functions (which may include select, insert or update on database tables) with this user, but I don't want to grant privileges on select, update or delete on tables.
I am using "SECURITY DEFINER" and then I grant execution, but I think it may be a little insecure. Am I right? is there any other way to do it?
Thanks in Advance.
Lamis
There's no way to hide the system catalogues from a user in PostgreSQL. If a user can't access the catalogues then they can't locate any other database objects.
If you really can't afford to let them see the structure of the db, you'll need to prevent them connecting. Build some sort of middle layer with a simple API that calls the db.
SECURITY DEFINER is the standard way to provide limited access at a higher privilege level. You have to be careful with any function arguments that can end up in a dynamic query though. That's the same "bobby tables" issue as with any dynamic sql building though.
How about
REVOKE SELECT ON pg_namespace FROM my_user;
REVOKE SELECT ON pg_catalog.pg_database FROM my_user;
You won't be able to see anything, but you'll be able to make queries if you know the namespace and table name.

Resources