improve security at "database layer" - only select queries allow - sql-server

I am building a application in silverlight which will enable users read information about their payment. Their login and password will be save in table in db.
It is possibility to improve security in my app by limiting what data a query has access to? For instance i want to prevent a user from selecting data they do not own. A limitation is that my application is using a its own table for users, so i cannot use GRANT PERMISSION :/. I am using Linq to build my sql queries.
This question is from my teacher who "suggest" me to improve security, so if it's impossible - it's no big deal ;)

Well, it is kind of a vague question you've asked, but I'll hazard a stab at it.
You must be doing some authentication on the user's identity to only be showing them their payment, as opposed to someone else's payment. So, if you can do that, you should be able to create triggers that disallow any insert, updates, or deletes on your tables from those same identities... I don't think this is a very robust or scalable solution, but it's an idea.
CREATE TRIGGER [x] ON [TABLE] FOR INSERT
/* Disallow Users to insert */
IF EXISTS( SELECT 1 1 FROM [Users] WHERE [Users].UserID = [Y])
--Rollback transaction, set error, etc
Do you have any more details? Anything else could be helpful in finding a better solution.

A fine tuned access control for database resources is a very uncommon method of securing your application. User level access control is best implanted by the application. The sql user account used by the application should be as restricted as possible. For instance it should only be able to use the database(s) it needs to function, and nothing more.
There is 1, and only 1 project that has fine grained access control for a sql database, and that project is SE-PostgreSQL.
"It can provide fine grained mandatory
access control to various database
objects such as tables, columns or
tuples and can apply consistent
authority of remote/local client
integrated with operation system
independent from database
authorization."

Create a view named 'MyPayments', on the 'Payments' table. Make sure you have a WHERE clause in the view definition, so that the view returns only the relevant data to each user. Here is what the WHERE clause of your view will look like:
WHERE PaymentOwner = SUSER_SNAME()
The SUSER_SNAME() system function returns the currently logged in user's login name. If the first user logs in with the login name 'User1' and inserts a row, his/her login name is stored along with the row. The SUSER_SNAME() function in the WHERE clause of the view definition makes sure 'User1' see only those rows that have the 'PaymentOwner' column set to 'User1'.
More here

Related

Azure SQL: How to be notified if someone exports the database?

I run a system based around an Azure SQL Database.
A few different team members need to have read access to this database to perform support and management tasks.
However, I am concerned that by having access to the database, one of them may - with the best of intentions - export the database and manage the backup carelessly, resulting in a data breach.
How can I get Azure to notify me if somebody backs up the database (or downloads more than X million rows, maybe?) These people need to have database access, I would just like to know if they use it in a way that could cause a security risk for the platform.
You can use Extended Events for this.
To set it up on Azure you can follow this tutorial.
For your case
You create a session
You Select the rpc_completed (docs) event and click configure
In the Global Fields tab you can select the fields you want to keep track of. I.e.: Username, sql_text, session_id, database_name, client_*
In the Filter tab you can select a filter condition. In your case row_count would be appropriate.
When malicious users are smart, and retrieve small numbers of rows and page them this will go undetected. So a second filter could be Querys without WHERE clauses or a different approach based on your case.
When extended events are setup to write to blobstorage. You would have a different process (Azure Function, Runbook, ...) that would inspect the result and alert you.
Extended events are moslty used for troubleshooting, they replace SQL profiler. So turning it on a production server may have a performance impact.

Alternative to cross database trigger in Azure?

I have a website that does two things:
1) It allows users to select a group from the dropdown menu and push a button to run a report on a group that already exists in our database.
2) If a group is not already in the group list, a second page allows the user to input some group information to our database (with the idea that they could then run a report on that group.
When the website coder created the website, he put the dropdown menu options into one database and has the collected group information going into another.
Problem:
Once the new group information has been collected, I need to update the drop down table in the other database to include the name of the new group.
The easiest fix would probably be to have the website update both tables, but we not longer have the services of the guy who coded the website and I need to get this fixed. So, I want to fix this on the database side.
I was thinking I could do that with an insert trigger, however, other strings state that cross-database triggers aren't a kosher thing to do.
Further complicating the matter, our databases are both hosted on Microsoft Azure. I found a post about doing a select from two statements on Azure and am trying to work through it to create a cross-database query right now. I am still unsure how I will solve the problem of needing data in both databases though.
What can I do?

grant read access on a view but not on it's underlying tables from other databases

I want to grant read permissions for a user for a view which joins 2 tables from another database.
I don't want to:
give him permission on the database where the tables are or add him as an user there.
Make him the owner of the view/schema due to the security exploits.
I don't want to create first a table, or variations of a hack table with a truncate and a stored procedure which inserts the data on a trigger.
Can this be done somehow? Maybe there's something I missed and you guys might know.
I have read these posts but they didn't solve my problem:
Grant SELECT permission on a view, but not on underlying objects
Grant Select on a view not base table when base table is in a different database
https://msdn.microsoft.com/en-us/library/ms188676.aspx
https://dba.stackexchange.com/questions/89632/sql-server-grant-select-access-to-a-user-in-a-view-and-not-in-its-tables
Thank you
Edit:
The easiest solution I came up with, after some research, is activating the cross database ownership chainingoption on the database where I'm placing the views and granting the read permission to the users. This might be in contrast with my 2nd point of things I'm trying to avoid. Is this a good idea?
Give them a login to another database on the same server, and include only your single view, with the view pointing to your secure database. Don't give that login any access to anything but the database with the view in it, and only read access to that single view. Obviously, you'll have to fully qualify your table name (e.g., from SourceDB.dbo.SomeSecretTable).
What I ended up doing:
Create an active directory group.
Add users to the AD group.
Create a login for the AD group mapped for the source DB and target DB.
Add the user on the target DB and give him permissions only for the requested views.
(Optional) Added the group on all the databases to deny select.
Couldn't find a solution for my original question without the AD group.

SQL Server Security Option w/ Intermediate Check Option? What does that mean?

This afternoon I was reviewing the security for a user in my SQL Server, in SQL Server Management Studio. I opened the Database User's Properties dialog, and went to the Securables section.
As I was cycling through the tables and stored procedures that this particular user had access to, I noticed that one of the data tables had the the Update option checked in an intermediate state. What does that mean? You can either update a row, or you can't. There is no in-between. I've included an image for reference. I would just fully check this option and save it but I'd rather not screw with the DB if this serves a worthwhile purpose.
I believe that means that that permission has been inherited and wasn't explicitly set for that user.
The GRANT statement can assign
permissions to a group or role that
can be inherited by database users.
http://msdn.microsoft.com/en-us/library/bb669084.aspx
I'm trying to find something that specifically spells out that's what the checkbox looks like in the above situation.

Dimension Security in SSAS & SSRS

I am stuck with a problem of implementing security at dimension level in SSAS. Here is what I did -
1. Defined a role in SSAS and applied security at dimension level (Unchecking cube dimensions that I don't want this role to access and setting Allowed & denied Sets).
2. Tested using Cube Browser, it worked fine.
3. Tested using SSRS, no change, I was still able to query the dimensions & get results that I don't want.
Question - Is it possible to propagate the security I define at Cube level to SSRS? I would like to believe yes it is.
If yes then here is what I need -
Users will logon to the Report Manager using Windows Identity (Integrated Authentication on IIS turned on -done)
Capture this identity to find out SSAS role that they belong to - I guess this would be through a query, does not seem to work automatically (How to do this?)
User works within the restrictions of this role in SSRS (role based security applied at SSAS level) i.e. if dimension X is not available to user, he/she should not be able to query it. (How to do this?)
I have referred quite a few blogs on this and even found one - http://www.sqlmag.com/Article/ArticleID/96763/sql_server_96763.html
but this one seems to have more information on how to set it up within SSAS, rather than how to use this in SSRS.
Anyone who has worked on this approach OR have an understanding of this please let me know.
I think you need to look at your datasource in SSRS on the report server, and make sure it is set to use the logged in users windows cred's once authenticated, it might be what you are looking for.
All you need to do is:
In the data source in SSRS report, specify the Role Name created in SSAS database like this:
Data Source=LOCALHOST;Initial Catalog=XXXXX;Roles=RoleName
Thanks
Sameer
I haven't done this in SSAS, but I've done it in the engine. Jeremiah Peschka has a blog about row-based security setup, and if you're going to do this with integrated Windows security, then you can use the user_name() function to grab the current login's name. You'll be using a lookup table for each dimension, with a row for each dimension row plus the user's name. When querying, join to the dimension security table like this:
FROM dbo.Customers cs
INNER JOIN dbo.CustomersSecurity css ON cs.CustomerId = css.CustomerId AND css.UserName = User_Name()
That way, your join will only return records for customers that the user can see.
The drawback is that if you're using partitioning, the engine won't build a good execution plan to only pluck the right records from the right partitions based on what your user can see. For example, if you log in as a user that can only see records in Florida, and your data is partitioned by state, it won't matter - the engine will still scan all partitions, because it won't be able to predict the user's info when the plan is built.

Resources