Superuser Role Specific to certain Databases in PostgreSQL - database

I have created a User Role with superuser privilege. I have around 30 Databases on my server. I want to assign this role to only only DB. The current role lets the user access all the DBs as super user. How can I restrict him from accessing other DBs as super user.
This is the that I have for assigning superuser:
CREATE ROLE fc LOGIN
SUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
Can someone help me with this?

As #Craig explained, you can't (and even if you could, it would be fairly pointless).
The usual way of implementing restricted superuser permissions is to connect as an existing superuser role, and create SECURITY DEFINER functions containing a limited set of approved commands. These functions will now be executed with the privileges of the creator rather than the caller.
But you need to be very careful not to open any injection vulnerabilities, because everything within the function will be run as superuser. E.g. the caller could write a custom = operator which grants them superuser rights, and put it in their search path, so you need to be absolutely sure that you're using the = in the pg_catalog schema.
At the very least, you should:
Create all of these functions with the clause SECURITY DEFINER SET search_path TO pg_catalog, pg_temp. The pg_temp schema must always be included at the end of the list (if omitted, it will be implicitly included at the start).
Schema-qualify any other tables, functions, etc. that your function references (e.g. public.MyTable instead of just MyTable), and make sure that all of these are superuser-owned (so that callers can't put malicious code in triggers, etc.).
Never put user input in a dynamic query string (EXECUTE 'SELECT ...') without exhaustive validation.

There is no facility in PostgreSQL for a database-specific superuser.
It would not make sense anyway, since generally operations that are superuser-only are things that permit relatively easy escalation to greater control over the database system.

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.

PostgreSQL Grant user access to execute functions without table permissions and with RLS

In a multi tenant database table structure, a user can only see the data that he has access to, which is achieved by RLS. Additionally, the user can only execute functions and are not given permissions to tables used inside the function. I'm aware that we can use security definer in the function to execute on the owner perspective but the owner has access to all tenants data and then the user who executes it is able to see all. How can I give permission to user who can only execute function and can only see his own data without giving him SELECT permission on tables?
Use SECURITY DEFINER on the create function. Be sure to notice the security warning Writing SECURITY DEFINER Functions Safely section.

SQL Server roles and permissions

I really need some advice about adding roles at the server level and apply some permissions that will be applicable to each database on my server.
Basically I need to two roles read only and read write.
The read will have permissions to select and see any object
The write will have permissions to select/insert/delete and execute any object
I want to create a server role, then a login associated to this role (which can be a AD group) and after that for each database create a user that will inherits all permissions from the server role.
So on each database, I will have each user that belongs to the server role created, the problem is to clearly define the permissions, is not straight forward in my opinion.
What I can see, I cannot assign read or write to a role and then use it on each db, on the contrary on the General tab of the server role I have a bunch of permissions that is not clear which one to use for this purpose.
Maybe I'm doing it wrong but I want to have something at the server level and not define the same role on each db for that purpose. I'm using SQL server 2014.
The short answer is you can't.
Generally, server-level permissions are not propagated down to individual objects within databases. The only exception is a sysadmin role, which I would strongly encourage you not to use for this purpose, as you would essentially give up the control of the entire server instance to every member of it.
As a kind of a shorthand, you can use built-in database roles to save yourself a bit of trouble. For read-only access, a membership in db_datareader role is usually enough, unless you have stored procedures that return datasets which this role is supposed to be able to execute. There is also a similar role for modification, db_datawriter, but it doesn't cover the execute permission. So you will have to create a custom role for that:
create role [DataChanger] authorization [dbo];
go
alter role [db_datareader] add member [DataChanger];
go
alter role [db_datawriter] add member [DataChanger];
go
grant execute to [DataChanger];
go
-- Now you can add your members. Here is a reader
create user [Domain\MyUser1] from login [Domain\MyUser1];
go
alter role [db_datareader] add member [Domain\MyUser1];
go
-- Writer
create user [Domain\MyUser2] from login [Domain\MyUser2];
go
alter role [DataChanger] add member [Domain\MyUser2];
go
These permissions will automatically pick up newly created objects, without you having to explicitly add new permissions after every schema modification.
You will have to do this in the context of every user database that you want to manage in this way. You can probably create a SQL Agent job which will run periodically and introduce these changes in any user databases which don't have them already (for example, if a database has been restored from earlier backup, or brought from another server, or a new one was created). Also, since you can't loop through databases in static code, you will need to wrap it into a dynamic SQL and loop through sys.databases, or maybe via an undocumented sp_MSforeachdb system stored procedure. Oh, and don't forget to remove all these go statements from dynamic code, as they are not part of SQL, and are only recognised by SSMS and sqlcmd.
P.S. All that being said, I hope you are not going to manage any production databases in this manner. I don't even know where to start on how insecure this approach is.

SQL Server permission types

My team has recently moved into a more formalized system of SQL Server database auditing and deployment controls, and as a result several permissions have been restricted.
Many of us are not familiar with SQL Server security, and have encountered scenarios where we deploy something only to have a permissions restriction on, say, TRUNCATE TABLE denied in production.
It's just an annoyance at this stage, but I've tried to find some consolidated list (cheatsheet? cribsheet? reference lookup?) to easily check against for such functions so that it doesn't happen so easily, but I haven't found any.
I know that the MSN article for each function lists these, but I don't want to have to individually browse to the specific website for every common and rare function just to check, especially if I have to do it more than once because I forgot (for example).
The closest I found were sites like these:
https://www.mssqltips.com/sqlservertip/1718/database-level-permissions-for-sql-server-2005-and-2008/
https://www.simple-talk.com/sql/database-administration/sql-server-security-cribsheet/
...but they were incomplete (couldn't find TRUNCATE in both of them) and a little long: I'm hoping there's a table somewhere that simply put 'action -> action name -> permission name -> server/table level -> default role' or something together in one place.
Is there such a list somewhere?
Unfortunately I am not aware of any document that shows every action possible in SQL Server with the permissions required for it. Such a table would be impractical as there are a huge amount of possible actions, and some actions require multiple permissions, including scenarios where the permission requirements would change according to sub-portions of the action.
For the scenario you are trying to solve, it seems like you are using modules (SPs) to clearly define the actions allowed to the non-admin users, correct? In that case, you may be able to use digitally signed modules to grant the appropriate permissions when executing the SP instead of assigning the permission directly. For example:
CREATE USER [low_priv_user] WITHOUT LOGIN
go
CREATE TABLE [dbo].[myTable](data int);
go
CREATE PROC [dbo].[sp_truncate_my_table]
AS
TRUNCATE TABLE [dbo].[sp_truncate_my_table];
go
GRANT EXECUTE ON [dbo].[sp_truncate_my_table] TO [low_priv_user]
go
-- Will fail due to permission
EXECUTE ( 'EXEC [dbo].[sp_truncate_my_table];' )AS USER = 'low_priv_user';
go
-- Create a certificate to sign the SP,
CREATE CERTIFICATE [signing_cert]
ENCRYPTION BY PASSWORD = '<you_could_use_masetr_key_instead_of_p#55w0rD5>'
WITH SUBJECT = 'demo - module signature';
go
-- sign the SP
ADD SIGNATURE TO [dbo].[sp_truncate_my_table] BY CERTIFICATE [signing_cert]
WITH PASSWORD = '<you_could_use_masetr_key_instead_of_p#55w0rD5>';
go
-- destroy the private key
ALTER CERTIFICATE [signing_cert] REMOVE PRIVATE KEY;
go
-- Create a user for the certificate & grant it all the permissions you would need for running teh SP
CREATE USER [signing_cert] FROM CERTIFICATE [signing_cert];
go
GRANT ALTER ON [myTable] TO [signing_cert];
go
-- Permission check will be OK for the low privileged user
-- You control what this user is allowed to do via SPs
EXECUTE ( 'EXEC [dbo].[sp_truncate_my_table];' )AS USER = 'low_priv_user';
go
As you can see, I created a module that allows the caller to call TRUNCATE on a table, without granting ALTER permission directly to the user.
Ideally, when using this mechanism you would like to follow the least-privilege principle, and grant only the permissions you require and nothing else; but if you are having trouble finding the exact permissions you need, you may use a shortcut: GRANT CONTROL TO [signing_cert].
Obviously such shortcut has significant security implications, as you are literally granting full control of your database to the signed code (including dynamic SQL executed within these modules), but if you decide to do it, I would recommend the following precautions:
Destroy the private key to prevent anyone from abusing it
Do not use dynamic SQL within your signed modules (or at least make sure you are not subject to SQL injection)
If possible, avoid giving CONTROL permission on modules where you can grant the minimum privileges.
Audit all activity on your database.
I am also including a copy of the SQL Database Engine Permission Poster link, which may be useful.
I hope this information helps.

Is it possible to use SqlBulkCopy in SQL 2008 without permission 'db_datawriter'?

I want to limit my database possible access ways to only using stored procedures. Everything works fine except System.Data.SqlClient.SqlBulkCopy. I'm using it only in one class for massive data import.
Is it possible to avoid this problem?
I tried to grant a right before calling SqlBulkCopy and remove it after:
EXEC [db_mod].[sys].[sp_addrolemember] N'db_datawriter', N'my_user'
EXEC [db_mod].[sys].[sp_droprolemember] N'db_datawriter', N'my_user'
but such approach raises an error:
User does not have permission to
perform this action.
I'm executing it under the same user. How can I allow what I need?
The error described, following an attempt at sp_addrolemember(), is related to the current user not having the necessary privileges to alter account and security settings.
With regards to running SqlBulkCopy, it requires write privileges, and the db_datawriter role is a convenient way to provide these, but maybe you can consider alternatives. For example, rather than increasing (if only temporarilly) the security privileges of the current account, you can modify the security settings associated with this particular database/tables.
Changing the security settings of "securables" such as database objects, also requires some administrative privileges, but these may be associated with the database ownership, and hence may be available to you even though the privileges of changing an account are not.

Resources