SQLServer, temporarily disabling row level security - sql-server

I have implemented row level security in SQLServer in Person table (to meet GDPR requirements) so that a basic user can see only subset of personal records. The
Person table has some data (RFID tag) that must be unique in the system. So my app checks that there is no duplicate RFIDtag.
How to do this check when RLS is on, because the query only sees a subset of rows, but the RFID must be globally unique ? What could be the best way to run this query with temporarily disabling RLS ?
My first idea is to use a stored function, to perform the check. The function executed as 'sa' user sa could see all rows. Any other (simpler) ideas ?

The UNIQUE index is the safest approach, like said in #Jeroen's comment.
Disabling row level security can be needed in other contexts, though. When needed, my suggestion is:
Create an 'admin' user just for this (CREATE USER admin WITHOUT LOGIN;)
Include logic in your validation function to account for this user:
CREATE FUNCTION Security.fn_securitypredicate(#param as VARCHAR(100))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS Result
WHERE
/* Your logic here */
OR
USER_NAME() = 'admin' ;
This way, when you are impersonating 'admin' user all records are accessible. Any other user, your row level security logic still applies.
To impersonate the user when running a query:
EXECUTE AS USER = 'admin';
SELECT * FROM MyTable;
REVERT; -- Returns to the original user context

Related

Block access to column without changing query

I have a Microsoft SQL Server with data that needs to be protected (certain sensitive columns of some tables) and an application that queries that database like this:
SELECT BoringColumn, SensitiveColumn FROM Table
I have the following restrictions:
I have multiple users (3-4) each with different columns visible or not.
In this example SensitiveColumn should not be accessible.
I can not directly update the queries that the application sends
What did I try already:
I tried to use SQL Servers Dynamic Data Masking feature. However it's not granular enough, you can just turn it on or off per user but not just for some columns. And its can leak data in queries, the link above explains that as well.
I know I can just deny the user SELECT on Table.SensitiveColumn.
However then any existing query asking for the table just breaks with permission errors.
What other options do I have left?
Ideally I would like something that replaces the query on the serverside and executes something like this:
SELECT BoringColumn, 'N/A' as SensitiveColumn FROM Table
I think I found a possible solution:
Change the table structure - Rename the SensitiveColumn to a different name, and add a computed column with the old name of the SensitiveColumn, that will show results based on current_user.
CREATE TABLE tblTest
(
boringColumn int,
SensitiveBase varchar(10), -- no user should have direct access to this column!
SensitiveColumn as
case current_user
when 'Trusted login' then SensitiveBase
else 'N/A'
end
)
The one thing I'm not sure about is if you can deny access to the SensitiveBase column but grant it to the SensitiveColumn.
I'll leave you to test it yourself.
If that can't be done, you can simply grant select permissions on the SensitiveBase column only to trusted login and deny them for everyone else.

Azure DB - How to give 1 user read-only permission for 1 table

I've been reading many answers but I am too weak at TSQL to filter out what I need.
I created a contained user for 1 DB...
CREATE USER appuser WITH PASSWORD = 'strongpwd';
So I need to allow a user in to read only the contents of 1 table - tableA (there are others in the DB) and do absolutely nothing else in the DB.
I do not want to affect any other users. I just want the user to be able to access the DB via say SSMS, see only tableA (well this is not that important), read it.
There are two ways one is to directly grant explicit SELECT only on Table 1 and the second one is to create a role, grant SELECT to role and addd the user to the role. Typically second way is the preferred way and can be done as below
CREATE ROLE [role_name]
GRANT SELECT ON [Table] to [role_name]
EXEC sp_addrolemember '[role_name]', 'appuser'

ORA-01031: insufficient privileges on insert

There is a change in data type of e one column from NUMBER(4) to VARCHAR2(4).
DBA did the conversion of exiting values.
Now When we are trying insert the record into table using proc * c code it is giving error "ORA-01031: insufficient privileges".
From SQLPLUS we are able to insert the records. After sometime problem gets disappeared. Once DBA rebuild the table and problem disappeared.
This problem occurs after every time we refresh the testing environment with new changes.
Run this line:
grant insert on [table] to [user]
change [table] to your table name and change [user] to your user.
There are some possibilities.
Double check your table privileges by running the following SQL command:
SELECT *
FROM dba_tab_privs tp
WHERE tp.owner = '<YOUR_OWNER>'
AND tp.table_name = '<YOUR_TABLE_NAME>';
In the case your privilege is granted through a role make sure the role is enabled by checking that the GRANTEE above, in this query below, is shown with the attribute "DEFAULT_ROLE" = YES.
SELECT * FROM dba_role_privs rp WHERE rp.grantee = '<USER_RUNNING_THE_INSERT>';
If it's not, and assuming there is no security issues with your DBA and application design, you can enable it by running this:
alter user <YOUR_USER_RUNNING_THE_INSERT> default role all;
Then again, make sure if you're recreating the table, that every time you drop it and create again, you run your grants accordingly.

prevent some user from seeing db2 tables structure

How can I restrict some users in DB2, not to see the table structure. I set the user privilege and restrict user from table access. so that user can not select data or change table but still can see the table structure or describe it.
This problem refers to row access in tables which is added in db2 version 10.
I had this problem too.
you can use this version - if applicable- and restrict user access from specific table structures.
You need to remove the select grant on catalog tables. For example, the following query should return 0 rows when executing with q restricted user.
db2 "select tabschema, tabname from syscat.tables"
All tables and views in the following schemas should not have select on public, nor in any group the restrictive user is in.
sysibm
syscat
db2 revoke select on SYSIBM.SYSTABLES from username

Triggers in sql server 2008 management studio

I am trying to set up the trigger in a way that when the administrator (not users) make any changes to the database, all the changed data with the administrator name and time gets saved in the audit table (already created) that has all the possible fields.
I have created triggers on each table for any sort of updates in those tables. The trigger saves the information in audittable. However, i want to restrict this action for administrators only. Like I only want to keep the record of changes made by adminsitrators with their name, time and changes made by them(I have a separate table for adminsitrator names, username, pw and all that).
Can someone please help me with that.
Thanks
To get the user you may use:
server level (login)
select system_user , suser_sname() , suser_sid()
db level (db user)
select session_user , current_user , user , user_name() , user_id()
Than and check that this user is admin or not in that additional table.
You can try one of these two functions, depending on what you define as "administrator".
SELECT IS_MEMBER('dbo'), IS_SRVROLEMEMBER('sysadmin')
The IS_MEMBER function evaluates the database role and the IS_SRVROLEMEMBER evaluates the server role. So, if you want to know if the user is a database admin, you would use IS_MEMBER. These will work for user-defined roles as well as built-in roles.
UPDATE:
Here's an example of the trigger that would add data to the audit table when a server administrator inserts data to the table.
CREATE TRIGGER trg_InfoUpdates ON tblCustomerInfo
FOR INSERT AS
IF IS_SRVROLEMEMBER('sysadmin') = 1
BEGIN
INSERT INTO tblAuditLog (CustomerID)
SELECT CustomerID
FROM inserted
END
;

Resources