I have to execute some queries in Firebird, but I need to hide "query source" from viewing in mon$statements or any other log in database.
That's because the query has some business rules that I can't expose to other people.
Is there any way to do it? Or some "trick" that I can use?
There is no way to do this. However MON$STATEMENT only shows your own queries, unless you are SYSDBA, the owner of the database, or a user with the RDB$ADMIN role (then you can see all queries). Other then MON$STATEMENT, there is also the trace facility which allows people with sufficient access to see queries (either on the server or through the service api). People with insufficient access to the database can still see queries if they can see the network traffic between the application and the database server.
The only way is to not give any form of access to the database server to people who should not be able to see the queries. This can be done by hosting the application as a webapplication, or putting a webservice or other form of middleware between the database and the real application.
Related
So I wanted to know if there is an acceptable method to Allow SQL Injection.
Example:
Limit permissions on the table(s)/database(s)
Why you ask?
My employer wanted to devise a way to test the skills of applicants, one suggestion was to allow resume submissions via SQL Injection.
Any thoughts? suggestions?
You could use roles. Create a role for the web application (or whatever) that is used to connect to the database. Limit this role to only permit INSERT and access to necessary tables for applying. Applicants with access to your database through the application could then only use SQL injections to add their resume.
It may be possible for someone more talented in SQL to use injections in a way that increases the role's permission. But I think if the role had limited access to only specific tables and didn't have CREATE or GRANT privileges, the user wouldn't be able to create new roles.
Here is some information on roles to get you started:
Adding Roles to MySQL with MySQL Workbench
Creating Roles in PostgreSQL
GRANT command - used to add privileges to users on table, database, etc. This page is for PostgreSQL, but MySQL is very similar (see this SO answer)
Given that the reason behind this is to test people's ability, create a database with data you can afford to lose. Set up a form that posts to a coldfusion or php or java or .net or some other type of page which connects to that database.
On the form, put a textarea and submit button. On the form target page, log what they put in the textarea. Compare the log to the database to see how it turned out.
Then test to your heart's delight.
When developing an application where users connect with their native database logins, I don't need to care about SQL injection right? The reason being the users can execute any SQL they want anyway. (There are places where admins execute CREATE LOGIN and CREATE USER statements and these have to be dynamically built.) I'm talking about a native Windows application on the LAN.
Well, SQL injection is a possibility to execute SQL, so with the SQL shell access, everything required for "SQL injection" is already authorized. However you still need to care if users run as non administrators, probably being restricted which tables they can access, and your system sends some additional SQL commands while logged in with higher rights (create user, etc). Use prepared statements for such a code.
If you mean that you are building a web application, and using users' database credentials to connect to the database, yes, you do need to worry about SQL injection.
Most databases restrict permissions based on objects - tables, views, stored procedures etc. So, a user logged in as "Bob" might have access to table "sales", but not table "payments".
The database does not restrict access to rows in tables (for instance). So, a user connected as "Bob" who can exploit a SQL injection bug in your code can delete every record in the "sales" table. You probably don't want that.
If user "Bob" also has direct SQL access, they could, of course, simply run that statement at a SQL command line - but usually, web applications are available where direct SQL access is not. Your web app may be put on the intranet to begin with, but you can't guarantee that won't be opened up in the future.
Given how easy it is to prevent SQL injection attacks when you're building the app, and what a pain it is to fix them later on, I see no real reason not to prevent them in the first place.
As a matter of fact, "SQL injection" is a common misconception.
Being unable to properly format their queries, folks invented an "sql injection" thing as an excuse.
While properly formatted query will serve 2 purposes at once:
it will always be syntactically correct, no matter what data sent in.
as a side effect it would be invulnerable to that notorious "SQL injection" thing.
I doubt you want your queries to fail because of some unexpected symbol. So, no matter of some "injection", you have to properly format it. But once formatted, there will be no injection anyway. So, you have to concern about format, not injections.
I also have a feeling that letting users to login with database credentials is not quite a good idea.
There are two AD accounts, admin1 and admin2. Both are logged in to identical machines, both open SQL Server Management Studio and log in as the same SQL user to the same SQL server (using SQL Server Authentication, NOT using Integrated Security), and both run an identical query: "SELECT * FROM View1". However, admin1 receives many results (the correct result set), whereas admin2 receives an empty result set. This happens on every computer in the domain, regardless of windows version, wired/wireless connection, etc.
Why is this happening? Shouldn't SSMS be Windows account agnostic when using SQL Server Authentication? Any help would be appreciated.
The issue I had was a result of Microsoft Dynamics CRM, not SQL Server itself. I was using Filtered views, which return zero results to any user not using Windows authentication. I am not sure how I got the results I mentioned above, but trying again another day, I was never able to get results with SQL authentication, no matter what Windows account I was using. Likewise, I was always able to get results when logged in with Windows authentication.
You can either use the raw tables or hack the underlying view framework by inserting records manually that show the domainname as your SQL Server Authentication login id and granting not the CRMReaderRole but the standard DQL Role. Take a peek at the wonderful fn_FindUserGuid function which looks up the SystemGuid which the views all inner join to. Just fabricate this record and a few others and your good. If you reverse engineer their system you will see there is a way to trick the system.
Its essentially just the SystemUserBase, SystemUserPrincipals, UserSettingsBase.
Obviously this is not Microsoft recommended. ¯(°_°)/¯ But when you need an ODBC connection on a shared server which provides generic reports to many users outside of the wonderful CRM world you need to do this. You will NOT find another way outside of replicating data to another database but of course keep in mind dynamics is wonderfully dynamic and changes often. Good luck syncronizing environments.
In my opinion this system was obviously designed this way to sway users towards Microsoft products. Not saying I wouldn't do the same if I owned Microsoft. When you're forced to hack your forced to hack.
I have to access some customers databases being hosted in a shared environment. There are numerous databases being hosted on any given customers instance. So everytime I access a database I have to scroll and search.
I would like to be able to configure Management Studio to just go directly to the database I want to work with for a given connection and hide all others on that connection/instance. But i still want to be able to see databases on other instances i might be working with, i.e. local using the same Object Explorer.
If that not possible is there any reason why the web hosting provider would grant their customers the VIEW ANY DATABASE permission? Im assuming thats why I can see all the other dbs?
If i cant configure Management studio to do what i want as per (1) then I was going to email the provider and ask that they prevent me from seeing them from the "server" end. Would this be an easy thing for them to do? If they REVOKE the VIEW ANY DATABASE permission then that should solve my "problem" right? But would it create any others?
You will require access to the master db to effect the outcome you want. There are no options to configure Sql Server management Studio (SSMS) to do what you want.
So (1) is out.
(2) however is a go so long as your service provider play alongs. You are right they will have to
DENY VIEW ANY DATABASE TO youruseracount
which will require access to the master db. But before they do this they will have to set youruseraccount as the owner of your database.
sp_changedbowner 'youruseraccount'
The side affect of all of this is
a. You wont be able to see any other databases in the instance which is what you want.
b. Only one user will be able to use SSMS to admininster your database with the 'View Only My Db' list. This is because only one user can be the Database Owner.
..
Richard
2 articles describe it (no point if I copy/paste, really)
One and Two
I searched online a bit and couldn't find anything that really nailed the spot or covered the bases how to go about setting up users/roles on a database.
Basically, there would be a user that would be used to access the database from the application (web application in this case) that will need access to database for the regular database operations (select, insert, update, delete) and executing stored procedures (with exec to run stored procedures within other stored procedures/UDFs).
Then, we would also have a user that would be main admin (this is simple enough).
I currently have a development environment where we don't really manage the security too well in my opinion (application uses a user with db_owner role, though it is an intranet application). Even though it is an intranet application, we still have security in mind and would like to see what are some of the ways developers set up the users/roles for this type of environment.
EDIT: Web application and SQL Server reside on separate machines.
EDIT: Forgot to mention that an ORM is used that would need direct read/write access.
Question:
What are the "best practices" on setting up the user for application access? What roles would apply and what are some of the catches?
First, I tend to encapsulate permissions in database roles rather than attach them to single user principals. The big win here is roles are part of your database, so you can completely script security then tell the deployment types to "add a user and add him to this role" and they aren't fighting SQL permission boogeymen. Furthermore, this keeps things clean enough that you can avoid developing in db_owner mode and feel alot better about yourself--as well as practice like you play and generally avoid any issues.
Insofar as applying permissions for that role, I tend to cast the net wider these days, especially if one is using ORMs and handling security through the application. In T-SQL terms, it looks like this:
GRANT SELECT, UPDATE, INSERT, DELETE, EXECUTE on SCHEMA::DBO to [My DB Role]
This might seem a bit scary at first, but it really isn't -- that role can't do anything other than manipulate data. No access to extended procs or system procs or granting user access, etc. The other big advantage is that changing the schema--like adding a table or a procedure--requires no further security work so long as you remain within that schema.
Another thing to take into consideration for SQL 2005+ is to use database schemas to secure groups of objects. Now, the big trick here is that many ORMs and migration tools don't like them, but if you render the default schema [dbo] to the app, you can use alternative schemas for special secured stuff. Eg--create an ADMIN schema for special, brutal database cleanup procedures that should be manually run by admins. Or even a separate schema for a special, highly secured part of the application that needs more granular DB permissions.
Insofar as wiring in users where you have separate boxes, even without a domain you can use Windows authentication (in Sql Server terms integrated authentication). Just make a user with the same credentials (user/pass combo) on both boxes. Setup an app domain to run as that user on the web box and setup a Sql Server user backed by that principal on the sql box and profit. That said, using the database roles can pretty much divorce you from this decision as the deployment types should be able to handle creating sql users and modifying connection strings as required.
For a long time the SQL Server guidelines for application access to the database were to isolate access to data into stored procedures, group procedures into a schema and grant execute on the schema to the principal used by the application. Ownership chaining would guarantee data access to the procedure callers. The access can be reviewed by inspecting the stored procedures. This is a simple model, easy to understand, design, deploy and manage. Use of stored procedure can leverage code signing, the most granular and powerfull access control method, and the only one that is tamper evident (signature is lost if procedure is altered).
The problem is that every bit of technology comming out from the Visual Studio designers flies in the face of this recommendation. Developers are presented with models that are just hard to use exclusively with stored procedures. Developers love to design their class models first and generate the table structure from the logical model. The procedure based guidelines reuire the procedures to exists first, before the first line of the application is written, and this is actually problematic in development due to the iterative way of modern development. This is not unsolvable, as long as the team leadership is aware of the issue and addresses it (ie. have the procedures ready, even as mocks, when the dev cycle starts).
Create a user 'webuser' that the web application uses.
Only grant stored proc execute permissions to this user. Do not allow direct table read/write. If you need to read something from a table, write a proc. If you need to write data, write another proc.
This way everything is kept nice and simple. One app user, with only the relevant permissions. If security is compromised, then all the intruder can do is run the procs.