I want to protect my database better, because, if someone decompiles my program, he will have my sql uid and password and can use them to steal my data. How can I grant permissions to the sql user, that I use for my program, to SELECT and UPDATE only when there is a WHERE or a LIKE in the sql statement? Because if someone finds out the user, he can steal my whole table. Thanks.
This is allowed :
SELECT * FROM table WHERE username = 'username'
This is not allowed:
SELECT * FROM table
One of the advantages of using a Database View is that A database view helps limit data access to specific users. You may not want a subset of sensitive data can be queryable by all users. You can use a database view to expose only non-sensitive data to a specific group of users.
So, in theory, you might try something like
CREATE VIEW user_username AS SELECT * FROM table WHERE username = 'username'
in order to create separate views for every user of your application.
That being said, it is a very bad idea to do so. Also, if by decompiling, a user has access to a database containing ALL the users, the I am pretty sure there must be something wrong with the design of the application.
But, as very few details are given about the application in question, it is hard to advise as to how it should be done.
Related
is there a way to limit GRANT SELECT user#db with something like a WHERE?
I have variable "PROJECTID" to assess certain records to a particular project.
When user query all clients it should only show the clients from their projects. I do not want to change the interface for every user, so a select where statement will not help here.
Thanks in advance
I fear, there is no such thing.
But you could create database views using a WHERE condition and then give permissions to those views to your users.
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.
I would like to understand how hard this is to implement.
In unix, there are unix groups where certain people with a group can access certain folders and files.
I would like to apply the same concept into MYSQL where people could only access, view certain tables or even same tables but different rows ...
How can I achieve this? Would I have to use a different database system?
Gordon
This is a very common and simple approach. You can create users and specify which databases/tables they can access and what type of operations they can execute. See the mysql documentation on this
For instance:
--create the user
CREATE USER 'gordon'#'localhost' IDENTIFIED BY 'yourpassword';
--specify table and specific operations for that user
GRANT SELECT,UPDATE,DELETE,INSERT ON database.table TO 'gordon'#'localhost';
Short version: How can I write an SQL procedure to list which of several tables in a MySQL database a particular user has access to?
Longer version:
I'm writing a multi-user app that accesses a database with data for several branches of a company. The database has a number of lookup tables that any user can access, and a table for each branch that only authorized users can access. My strategy is:
Write a stored procecure that returns a list of the relevant tables for which the user has SELECT privilege.
From the app, call the procedure. If there's only one table returned, use it, otherwise let the user select which branch they want to access (e.g. for managers).
I'm having trouble figuring out how to write such a stored procedure. SHOW GRANTS FOR CURRENT_USER is an obvious possibility, but parsing something like:
GRANT SELECT ON Company.BranchABC TO 'auser'#'%clientdomain.com'
in SQL to figure out what the tables are seems way too messy. Doing a SELECT from the actual tables that hold the permissions also seems problematic, because I'd have to duplicate MySQL's logic for combining the permissions from the various tables (user, db, host, etc.)
Any words of wisdom?
You can see what privileges on which tables a user has:
show grants for 'user'#'host';
For example, to see the privileges of user1 (all machines in the network 10.25), run:
show grants for 'user'#'10.25.%.%';
I have never granted per table permissions to MySQL users before, but to do this, you would check that the TABLE_PRIVILEGES table in the information_schema database.
That should point you in the right direction.
MySQL users list and its privilege can be check with the Query.
select * from mysql.user\G;
http://www.thedevheaven.com/2012/04/retrieve-mysql-users-list-and-its.html