Say there is a relation Table(A, B, C) and I was given all privileges to it. I make a view V(A) viewing Table's A. Then if I am revoked of all privileges from the Table, what exactly happens to the view?
To my understanding, a view is a dynamically created abstraction of a table (if not materialized) when called. Since I do not have any privileges to the underlying table, I would not be able to call the view V, which needs SELECT privilege on the underlying table. So the view is essentially deleted from the system.
Is my understanding correct? What happens if the view is materialized?
No, this is not entirely correct. Pls note, however, that security models are different in all rdbms. Since you have put only mysql into the tag list, my answer will be mysql specific.
In mysql you can define the security model for a view using the SQL SECURITY option in the create view statement. This can be set to either DEFINER (user, who defined the view) or INVOKER (user, who executes the view). If it is set to definer, then mysql will check the access rights of the user, that defined the view, not those of the user, that executes it. If you have SUPER privilege, then you can use any user account as definer, not just your own.
Mysql checks if the definer or the invoker (based on the setting) has access to the underlying objects when a view is referenced. If a view uses the definer option and the definer has access to the underlying objects and you do not, the view will still give you the results.
See access control for views in mysql documentation for details.
That being said, if you happen to have mysql v5.0.15 or earlier, then access rights to the underlying objects are checked only once: at the definition of the view.
Note: mysql does not support materialised views.
Related
I want limit the database access for a client. How can I define a explicit white list of SQL queries, witch can only execute a database user?
You would do the following:
Remove read access from all tables for the user.
Define views for each of the allowed queries.
Be sure that the security for the views is declared as DEFINER rather than INVOKER.
Voila! The user has access to the views, but not to the underlying tables.
I am currently trying to make a dump of my production database and deploy it in my development database.
Before i do so, i am willing to add a script that will change the definer of the database's tables to a definer that is used in my development database after the deployment is complete.
Is there a way to tell what is the current definer for a table?
Iv'e tried SHOW CREATE TABLE but it doesn't give me the definer of that table.
Note that i already have a script that does so for another schema, but i am not sure if the definer for the other schema is the same.
Also, i couldn't find an answer to this over the internet, so i am asking this here.
Thanks.
Databases and tables do not have a 'definer' (or DBO) in MySQL.
"users" are "GRANTed" permissions to access databases and/or tables. Will having different GRANTs solve whatever you are trying to solve?
A related topic... Stored Routines execute as the "invoker" or a specified "user" (your choice when creating the routine), but I don't think that is what you are asking about.
You, or others lead to this question, may be thinking of procedures/functions/triggers/events/views that may be correlated with the tables you're attempting to find definers for.
Stored Object Access Control
Stored programs (procedures, functions, triggers, and events) and views are defined prior to use and, when referenced, execute within a security context that determines their privileges. The privileges applicable to execution of a stored object are controlled by its DEFINER attribute and SQL SECURITY characteristic.
In which case, you may find the following queries helpful:
SHOW CREATE PROCEDURE proc_name
SHOW CREATE FUNCTION func_name
SHOW TRIGGERS FROM db_name
SHOW CREATE EVENT event_name
SHOW CREATE VIEW view_name
I use SQLyog to write procedures and functions in a remote MySQL database I am developing. The database has only one username/password. It is accessed via a front end executable application that I have written in Delphi and which is used by a couple of dozen different people, all using the same username.
When I use SQLYog to write a procedure using, for example,
CREATE PROCEDURE age_frequency_count(IN bin_size INT)
The resulting procedure gets the definer put in whether I like it or not, resulting in
CREATE DEFINER=<the_user_name>#<my_IP_address> PROCEDURE age_frequency_count(IN bin_size INT)
(I think this is being done by MySQL, not by the SQLYog DBMS.)
From reading the documentation and from posts here on SO, I have a rough, but rather confused idea of how the definer is used to say what permissions are needed to execute, or maybe alter, the procedure and what the procedure is allowed to do, but I would welcome some clarification.
Question
If my IP address is in the definer, can the procedure still be executed by other people who will be logging in from a different IP address (although with the same username)?
Can someone please clarify what the definer is doing? i.e. what can a connection from my IP address do that connections from other IP addresses can't?
I use the DEFINER clause to create a stored procedure with the security privileges of a powerful user that also has UPDATE, DELETE, SELECT, and INSERT rights to a particular database table. Then, I only grant EXECUTE on that stored procedure to a minon user (some people call it a www user, versus the more powerful wwwproxy user).
In this way, the minion can only execute designated stored procedures and has no UPDATE, DELETE, SELECT, INSERT, or other rights on a database table.
I hope that helps frame the idea behind the DEFINER clause. Use it to separate power from tasks.
You are correct, by default, MySQL uses the identity of the current user as the DEFINER when creating a stored procedure. This identity could be the identity of the front-end application (so to speak), or, like I said, you can use a proxy user that has normal table privileges. Then the application user would be the minion with only one privilege on the stored procedure, EXECUTE.
In short, if the default DEFINER user does not represent what the front end application uses to login to the database, and you want it to, then you need to change the stored procedure with ALTER, if possible.
On the other hand, the better idea would be to use the minon/proxy scenario. Application users on the Internet have no bearing on the IP that ends up in the stored procedures DEFINER clause. All that matters is the IP of where your app is logging in from to MySQL. Your app is talking to the database, not user agents on peoples' computers. However, that notion is, generally, a point of initial confusion. You are fine!
Hope that helps.
Let's say we have a public DNA database running on mysql. Database contains only complete data. In this scenario, some special users want to add experimental data to the database, which may not be complete or they don't want it to be visible to everyone. Instead they want the experimental data to only be visible to users with correct privileges. What approach would you take to achieve this?
Presumably these datasets are large, and performance is important. That means the privilege system should be as coarse as possible.
If I were doing this, I'd create a "public" database, and use the MySQL GRANT command to allow guest users to SELECT on that database.
For example:
CREATE USER 'guest'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'guest'#'%';
Then, for the nonpublic datasets, I'd put them into other databases, and be more selective about the users GRANTed privileges. For example, these GRANTs give two different users access to private information and the public information.
CREATE USER 'venter'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'venter'#'%';
GRANT SELECT ON celera.* TO 'venter'#'%';
CREATE USER 'collins'#'%' IDENTIFIED BY 'changethispassword';
GRANT SELECT ON public.* TO 'collins'#'%';
GRANT SELECT ON hgp.* TO 'collins'#'%';
A user who has SELECT privileges on, let us say, the public database and the celera database, can issue queries like this allowing seamless (if not optimally performing) merging of private and public data.
SELECT whatever
FROM public.AGCT
UNION ALL
SELECT whatever
FROM celera.AGCT
Of course, it has to make scientific sense to take the union of these datasets. That may or may not be the case.
Don't be alarmed at the idea of creating multiple databases. They really are nothing more complex than directories in a computer file system. A single server can deliver dozens of them without any problems.
MySQL is definitely up to this kinds of security. Hosting providers run multi-tenant servers routinely.
I would consider MariaDB (a MySQL-compatible database written by MySQL's founder) over MySQL, as it supports roles.
Neither of them support Row Security like Oracle does, but you can mimic it by adding an "owner" column with the name of the role that can select/update the row.
Add a WITH CHECK OPTION view that checks that the current_user is in the role specified in that column.
Add a trigger to set owner value properly.
update: If you can't alter the table but can add new ones, add a new one w same key as original, and add owner column, and join the tables in your view.
See
http://www.sqlmaestro.com/resources/all/row_level_security_mysql/
I have a web application which takes sql queries and produces the output in the form of a report. I don't want the user to MODIFY the existing database any way. To do this I decided to block all the CREATE,ALTER,DELETE,DROP commands at the web application level by just looking at the first word of the supplied query. This would stop the user from altering the existing schema or the instance of the database.
Recently I discovered that Microsoft SQL Server has the command SELECT * INTO NEW_TABLE FROM OLD_TABLE which allows us to create a copy of the the existing table. Are there any more commands of this kind which would allow us to modify the schema or instance of the existing DB by passing the web application filter ?
Any better ways to block the commands according to my requirements are also welcomed but I do not wish to take away the freedom of creating report using SQL queries at the cost of security.
Why Cannot I use Grant
I see that grant is one good option that I see from the comment as well as the answers but I will not be able to use them because the user supplies the DB details which I use to create the report along with the username and password. It is for the DB's table the user points to that I create the report
You can generate the reports from results of a query performed by a user with only read permissions. This implies management of the database connection to allow other parts of the application to manipulates the data ( you will need to connect as different users).
CREATE USER 'foouser'#'localhost' IDENTIFIED BY 'barpass';
GRANT SELECT ON db.table TO 'foouser'#'localhost';
Even if you use "SELECT * INTO NEW_TABLE FROM OLD_TABLE" you have to create the new_table first using create statement then you can use that statement.