How can I prevent users running UPDATE statements via a query builder - c#

We are building a reporting framework into our application, which necessitates the use of a query builder. Ultimately, we want power users to be able to build SELECT queries to be used to populate the report dataset.
Datasets are built using a DataAdapter (either MSSQL or SQLite). Are there any tools we can use to ensure that the queries built by the end user can only be SELECT statements?
EDIT:
As mentioned above, we target SQLite as one of our supported backends No DB permissions can be set on this platform.

Set right permissions to DB. It's the best solution.
EDIT:
For SQLLite you can set read only permissions for file - in the file system.

Give the user that you execute the SQL as only the db_datareader permission to ensure that they cannot do anything but read the data.
This question gives more info on how to do that:
How to give a user only select permission on a database

If the query builder is done in house, and if your query builder returns a the SQL statement in a string, you can parse it either looking for Update statements keyworks or with Regex, if you want to spare the users the trouble of creating an update query then realizing that they can't run it, then you should consider doing this check continiously as they create the query. Alternatively, you can use a third party query builder, like this one: http://www.activequerybuilder.com/, unfortunately i belive it doesn't support anything else but Select statements but it may be worth the shot.

I think all you have to do is wrap the QueryBuilder and expose only permited operations.
I is not good to do thinks the other way around, like letting the user construct a query and at the end you tell him it is not permissable.

Related

C# script to parse stored procedures and extract meta data

I have around 500 stored procedures that are used for our ETL process. I have been asked to identify all the source and target tables used by each stored procedure. So, a stored procedure could have a connection to an Oracle linked server, or another SQL Server. It could also be using an OPENQUERY to extract data from our transactional systems.
Since I have some basic .NET/C# programming chops, I was hoping to leverage the .NET RegEx class to get started. However, I am looking for suggestions on how I should approach this. I really don't have to reinvent the wheel if someone already has a solution for this.
As a context, we are working on implementing PowerDesigner to store metadata repository. So, we are looking to extract metadata from our BI reports (map reports to it's source tables/views) and our Informatica and T-SQL ETL scripts.
Thanks
I'd suggest a dual-approach. Firstly, I'd avoid using regex for something as complex as SQL Query parsing, especially since there are tools in place for this kind of thing.
https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.dependencywalker.aspx
The SMO library exposes a class that will let you connect to a server and retrieve a dependency tree for a given stored procedure. How to do this exactly is left as an exercise for the reader :)
However, this class won't pick up dependencies that are introduced via dynamic SQL or through OPENQUERY. If the number of procedures that do this are small, I'd recommend doing this manually, and then merging the results. You could use the SMO scripting capabilities to pick up all instances of either OPENQUERY or exec/sp_executesql; at least then you would have an idea of 'suspect' pieces of code.
Merging the results will be tricky. Not only do you have to manually update dependencies for procedures containing dynamic dependencies, but you have to update procedures that depend on procedures containing dynamic dependencies.
You can use a dynamic management view dm_sql_referenced_entities to get some dependency information from SQL Server itself but there are some limitations. Not sure if the Dependency Walker leverages this view, but the pros and cons are very similar.
The same main limitation that I know of and have experienced is that you won't get any dependency information for an object that is leveraged through dynamic sql. We have very contained usages of dynamic sql so I can feel pretty confident leveraging this DMV and manually accounting for the objects hit by those specific procs.
We don't do linked servers, but in my understanding is that those would show in this DMV. I don't know about the OPENQUERY ... I did a little bit of research but I did not test it out but I am guessing those would not be surfaced by the view. Like the previous poster said, you may need a two-pronged approach to get everything you're looking for.
And just for reference, a simple example of using that DMV:
SELECT DISTINCT
[database] = COALESCE(r.referenced_database_name, DB_NAME())
, [schema] = r.referenced_schema_name
, name = r.referenced_entity_name
, r.referenced_id
FROM sys.dm_sql_referenced_entities('dbo.procName_sp', 'OBJECT') AS r
WHERE r.referenced_id IS NOT NULL;
I wouldn't use C# for this. However, maybe something like this will do the job.
select *
from DatabaseName.information_schema.routines
where routine_type = 'PROCEDURE'
SELECT name, type
FROM dbo.sysobjects
WHERE type IN (
'P', -- stored procedures
'FN', -- scalar functions
'IF', -- inline table-valued functions
'TF' -- table-valued functions
)
ORDER BY type, name
Or, if you want SProcs and parameters:
select * from information_schema.parameters
Finally, this link looks pretty helpful for your situation.
http://blog.sqlauthority.com/2010/02/04/sql-server-get-the-list-of-object-dependencies-sp_depends-and-information_schema-routines-and-sys-dm_sql_referencing_entities/

How to get the execution plan using LINQ to SQL/ADO.NET

Is it possible to get the execution plan of a LINQ to SQL or ADO.NET Query programatically for displaying in debug information? If so, how?
Sure, there are 2 things you will need.
A custom implementation of DbConnection, DbCommand and DbDataReader. You can use that to intercept all the SQL sent to the DB. You basically set it up so you have a layer that logs all the SQL that is run. (we plan to open source something in this area in the next few months, so stay tuned)
A way to display an make sense of the data, which happens to be open source here: https://data.stackexchange.com/stackoverflow/s/345/how-unsung-am-i (see the include execution plan option)
Another approach is to do the diagnostics after the fact by looking at the proc cache. sys.dm_exec_query_stats contains cached plan handles which you can expand.

Run SQL statements from ASP.net application

I need to run sql statements from the application itself. i.e. the user can go into the asp.net applciation, gets a box and can run sql statements from there
I am already doing something like this
Can I rollback Dynamic SQL in SQL Server / TSQL
That is running dynamic sql
is there a better way to do this
Dynamic SQL is certainly the easiest way to do this. The alternative is parameterized SQL, but that would require having your users define and set parameters separately from the T-SQL.
You can simply submit the T-SQL string to SQL Server using the SqlCommand object; there's no real benefit to wrapping it in an EXEC or anything, as in the link you provided. You can do exception handling on the .NET side.
Also, if you want to support command batches, keep in mind that SqlClient and friends don't understand "GO", which also isn't an actual T-SQL command -- you will need to parse the input and break it into batches yourself.
I'm sure you understand that there is a big security risk in doing this, and that's it's generally not recommended. You might consider using a connection string that specifies a user with limited permissions, to help control / limit their access.
DO NOT DO THIS. What if the user types in sp_msforeachtable 'truncate table ?'...?
RunSQL.aspx utility might help. See Upload T-SQL and execute at your hosting provider using an ASP.NET page.

Storing reporting assemblies (.net) in a database

I'm developing a project where users need to build reporting queries using complex Linq statements to generate data sets.
The best way I could think of to compile these user-generated queries and then execute them is to use the CSharpCodeProvider object to build an assembly and then store the result in a database blob.
Is there anything wrong with this process? Also, how can I restrict the permissions of the user assembly to only allow execution against a limited set of objects that I provide?
Thanks!
You shouldn't have to save the queries as a generated assembly. A simpler way would be to save the SQL executed against the database for future use. Use the GetCommand method of the DataContext to get the SQL and persist it as a "saved" query.

LINQ to SQL Cannot create database [Schema Permissions]

For some integration tests I want to use LINQ to SQL to drop/re-create the test database. I've had this working fine before, however in this project the database is split up into several schemas.
When I try to run the ctx.CreateDatabase() command I'm getting this exception:
The specified schema name "xyz" either
does not exist or you do not have
permission to use it.
The login I'm using to do this has the role dbcreator - Does it need further permissions? Surely a login with persmissions to create a database should be able to create everything contained in that database also?
Update:
Since it looks like there isn't a solution to this problem using LINQtoSQL, does anyone have recommendations of any similiar tools to generate a db that are preferably free? Ideally I don't want to have to muck about hand writing sql build scripts.
From what I've read, the CreateDatabase() method is limited in what it can reproduce of the original database. It won't recreate things like triggers and check constraints, and I'm guessing it doesn't create custom schemas either. You may want to look into creating the database using a SQL Server .mdf file instead to work around this issue. See this blog entry for more details on some of the limitations of CreateDatabase().
I generally do this sort of work in NAnt to create, initialize the database, create users, add logins, etc....and also roll back capabilities. I have written on this topic quite a bit if you are interested:
Build automation with NAnt
Continuous integration with CruiseControl.NET
I will have to see if I can get LINQ to SQL to work in the way you are trying to use it...that sounds like what we used to do with NHibernate.
The dbcreator fixed server role grants you the permission to create a database. If you create a database, you are the dbo of said database and as dbo you have absolute power in the database, includding the power to create, alter and drop any schema and any object contained in any schema.
the problem with LINQ's CreateDatabase() is not permission, is code quality. The generated SQL code simply does not create the needed schema, so the Create table statements fail because the schema does not exist.
Your best choice, if you can afford it, is to add a VSTS Database Edition GDR R2 project to your solution and declare all your database objects in the Database Edition project (part of your solution). You'll be also getting the added benefit of storing all your database objects in a proper source control solution. The output of the Database project would be a .dbschema file containing the definition of your database. At deployment time (test or real) you would run the VSDBCMD Deployment and Schema Import tool to import your .dbschema into the target server. The tool is capable of doing initial deployment of your schema, as well as further upgrades (deploy only differences). The VSDB solution would allow you to controll all your database objects: tables, indexes, views, schemas, field contraints, table constraints, triggers, procedures, users, permissions, logins etc etc. It really covers all the objects that can be defined in SQL Server.
Actually LINQ to SQL does support schemas, but not every Sql Server edition does. To enable CreateDatabase() to generate them the DataContext must be aware that the target database does support them. It can be done by setting the provider on the DataContext:
[Provider(typeof(Sql2008Provider))]
public class CustomDataContext : DataContext {
...
}
Your user also requires db_dlladmin for that database.
I would definately look at Entity Framework, which I am beginning to look into these days. It's an OR/M, and will most definately suit your needs, and alot more once the next version is released.
Entity Framework is also a brain-child of Microsoft and can be found here: http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx
One thing to remember between LINQ to SQL and LINQ to Entities is that you are programming against a model, and not the database.

Categories