Is a simple MySql Database possible? - mysql

Steps:
I want a registered user to be able to insert values into a table.
Those values would only be able to be seen or edited by the user. (a few rows)
I have a registration/login page and insert form page complete and they can add do their respective jobs.
Here's the problem and i realize it probably a super simple answer:
How do I link the registration/login username to the values that I'm entering so that only that username has access to it?
Thanks,
Michael

You can create a MySQL user for each registered user and protect their data at the DB level. That's usually overkill for a web application.
What you probably want here is enforcing data owner at the data access layer. Associate the data to the user and restrict any data queries or updates to that user, i.e. any insert, update, select SQL statements would include the user id as a parameter.

Related

MySql grant permissions only to read something not whole table

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.

How many db-users should I create?

guys!
I need to ask you a question... I'm mew in programming business and if this question seems silly, please indulge me.
I have a little site where people have to register in order to post something. So I register every user in the database. I log into the db with:
$pdo = new PDO("mysql:host=localhost;dbname="MY-DB", "My-USER", "My-password");
The question is: when I log into the databse to do whatever operation I need (select, update, delete, insert) how many users ("MY-USER") should I create to login to the db ? Should I create one db-user for every users that registers on my site, or one one single user is enough to do the operations ?
Thanks.
In normal situations you should have additionally to a root user, which can create new databases and add new users, you should create one user per application which is accessing the database, so that a bug in one application wouldn't affect another.
In your case this means to have 1 additional user for your web application which has all permissions on one mysql-database and can create the necessary tables as well as read / modify data in those.
You should not use mysql as your user manager, instead create a table with the users, their (hashed) passwords, ... and manage them in your application.

Is it possible to modify the schema or instance of any database without using create, alter, delete, drop commands?

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.

Secure multi-tenancy in MySQL application

I have a JSP/MySQL web service where users interact with "processes" -- they can upload data, configure, view reports, etc for a given process. They can also create new processes or run reports that compare several processes.
Currently, the process id is specified in the URL (a GET parameter) so any user can interact with any process. I have been asked to add security and multi-tenancy to this service. For simplicity, let's say each tenant has full access to a set of processes, but processes may be accessible by multiple tenants.
My preferred approach:
Add a user table (PK_User_Id, password_hash, name, etc)
Add an access table (FK_User_Id, FK_Process_Id)
An SSL login page that stores the Tenant_Id in the Session
A process-select page that lets you choose a Process_Id that you have access to, and stores that in the Session
Almost every page will create its SQL queries based on the Session's Process_Id
"Cross-process" pages like Create, Select, and Compare will work off of the Session's User_Id instead
My boss thinks that this is not secure "enough" to satisfy an external code audit. He fears that a wayward developer could still write a query that exposes one customer's data to another, or something.
He wants me to also use ANSI SQL's built in ROLES (the app must stay DB agnostic) to create a db role for each user. The role will detail which tables the role has access to, which rows in shared tables, etc. This way, upon login, the Connection will be "safe" and no developer mistake can possibly cause issues.
Is this possible?
Are there such a thing as DB-agnostic "Roles" that work with MySQL?
Can the roles specify that you are allowed to add rows to a table iff the primary key is 'foo'?
Is my system "secure enough" by industry standards?
Here is what I do for MySQL multi-tenant with a single database to ensure data is private:
Create a mysql user for each tenant
Add a tenant_id column to each table
Use a trigger to automatically put the current mysql user into the tenant_id column on INSERT
Create a view for each table that only shows rows where tenant_id = mysql_user (do not include the tenant_id column in the view)
Restrict the tenant mysql user to only have access to these views
Since the application is using the tenant's mysql user there is no chance that they can accidentally get another tenant's data.
I was able to convert a large single-tenant mysql application to multi-tenant in a weekend with minimal changes. I documented the design here: https://opensource.io/it/mysql-multi-tenant/
use PostgreSQL instead, as it supports real schemas, unlike MySQL
if you have to use MySQL, do the following:
make one mysql user per tenant
add an indexed column to each table, tenant VARCHAR(16) NOT NULL
add a trigger to each table that sets tenant to the mysql connection username ON BEFORE INSERT
create a view for each table that sets WHERE tenant = mysql connection username. DO NOT include the tenant column in the select list
grant permission to the tenant user for views, but not for tables
And now the user can only see their own tenant information.
We had a similar discussion on multitenancy security and handling requests on so question. But in short I think storing tenantID in session is a huge security risk. User can go from one tenant to other and tenantID will remain the same, also tenantID should not be send through url.

different logins access different data from tables

I am using MVC 3, and mssql 2008 r2 and,
I was wondering if there is an automated mechanism that associates different logins to different data from database tables.
For example I want to create a calendar. But I want each user to view only his own entries. So I have a table Appointment with time and place. But I do not want to include an association from LDAP because I will need to do that in a number of places.
Adam
If you are not planning to do this in the application logic, then the only way I can currently think of to do this is through the use of stored procedures or table valued functions.
What you would do is create what are often referred to as CRUD (Create Read Update Delete) stored procedures for the tables. Obviously if you are only reading from the table(s), then only a read sproc is needed.
Within the stored procedure, you can put in logic to filter the results based on the user's login.
You can assign the user to a role in the database and give that role execute privilege on the stored procedure. Or if you are using a table value function, you would give the role SELECT privilege on the function. You would not give the user any privileges to view the table itself.
Ex.
CREATE ROLE CalendarReader AUTHORIZATION dbo;
GO
CREATE PROCEDURE Calendar_Get
AS
SET NOCOUNT ON;
SELECT
EventDate
,EventText
FROM
Calendar
WHERE
UserLogin = suser_sname()
;
GO
GRANT EXECUTE ON Calendar_Get TO CalendarReader;
GO
There is nothing else for it but to have your database be structured in such a way as to know which data belongs to each user. So your CALENDAR table is going to need a user_id column on it. If you are using any ASP.NET web-based application framework, including MVC, you have access to the authentication provider that your application uses.
For an MVC application, your controller needs to pass the user ID (i.e. HttpContext.Current.User.Identity.Name) to the data layer, which needs to use this value in the where clause.
Trying to do this implicitly will just get you into trouble. For example, if you need to have an administrator with access to multiple users' calendars, you can't use an implicit filter. You need to have your controller tell your data layer what it wants.