postgres schemas and roles in mySQL - mysql

I have been using PostGresSQL as the database for one of my applications. To support multi-tenancy, I used schemas and roles for each tenant so as to limit access and prevent data leaks in event of an SQL injection. I am maintaining a single connection pool and then doing a SET ROLE after determining the tenant context so he can access only his own schema. This all works well. However, what is the equivalent design in mySQL ? I saw that mySQL does not have "roles" and a schema / database is the same conceptually, how can I achieve something similar in mySQL ? I ask because I am designing another application and am being told to use mySQL instead of PGSQL.
Thanks

Since mysql does not have the concept of roles, you either have to use different mysql database users and databases to achieve the same logical separation of data. Effectively, after determining the context, you have to connect to mysql using a different myswl user account and a different default database. The drawback is that this solution will render connection pooling inert. Fortunately, in MySQL establishing a new connection to the database is quick and does not require too much resources.
Alternatively, you can use a single database and mysql user account and distinguish between you users on application user account level. Obviously, this means that your users' data will not have the same logical separation as you currently have, but you can still use connection pooling.
As a third alternative with limited number of users you can use the same mysql user account and default database to connect to mysql, but store actual user data in separate databases only accessible using separate mysql user accounts. However, in that default database create separate views for each and every table in the user databases. In the create view statement set the definer clause to the mysql user account that can access the given database where the table is stored and set sql security clause to definer. This way you can still use connection pooling, since the connections are made using a common user id to a default database. The client data will be logically separated in the databases. The drawback is that through the views within the default database all data will be accessible and any modification to the underlying data structure must be reflected in the views as well.

Related

How can I define a SQL-query whitelist for a database user in MySQL?

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.

dbConnect- Does cleaning data in R change data values in the real database

I am doing research on MySQL data. I used the dbConnect function to connect to the database and used dbReadTable to read a table.
My question is: if I start cleaning data to make it tidy using tidyr and dplyr, etc, will this change the data from the database (data that is stored in mySQL and was collected by researcher)
Or does cleaning data in R only change the data called upon in R and have NO EFFECT ON THE database.
I need a definitive, well-backed, and professional answer as the data I'm dealing with is pretty important and valuable.
Given a database connection, you can definitely modify data in the database by using any of the keywords such as INSERT, UPDATE, DELETE depending on the role of the database user;
One safe way to avoid any modification of the database is ask the database administrator (I assume you are not the one) to create a user that has only read access to it, and then connect the database using this specific user. Then you would be safe to do analysis without unintentionally injecting anything into your database because the database won't allow you to do so;
But most importantly consult with the database administrator before taking next step, this answer is just for giving a clue on how to do this safely from my personal perspective. No responsibility taken for the next move you made.

MySQL Privileges To Create Database

Is there a way to create a user in MySQL that have login access but no databases, but it allows the user to create a new database to a limit of 5 or what ever I decide.
So basically what I want is to give a user access to create his own databases, but I dont want him to see other databases, also he should be limited to create only 5 databases
There is no notion of "Database Owner" or "Database Creator" in MySQL, therefore there is no way to limit the number of databases created by a user.
Note: it is possible to put some restrictions at account-level, but not the ones you are looking for. You will need a third-party management tool for this.

Difference Between Schema / Database in MySQL

Is there a difference between a schema and a database in MySQL? In SQL Server, a database is a higher level container in relation to a schema.
I read that Create Schema and Create Database do essentially the same thing in MySQL, which leads me to believe that schemas and databases are different words for the same objects.
As defined in the MySQL Glossary:
In MySQL, physically, a schema is synonymous with a database. You can substitute the keyword SCHEMA instead of DATABASE in MySQL SQL syntax, for example using CREATE SCHEMA instead of CREATE DATABASE.
Some other database products draw a distinction. For example, in the Oracle Database product, a schema represents only a part of a database: the tables and other objects owned by a single user.
Depends on the database server. MySQL doesn't care, its basically the same thing.
Oracle, DB2, and other enterprise level database solutions make a distinction. Usually a schema is a collection of tables and a Database is a collection of schemas.
Refering to MySql documentation,
CREATE DATABASE creates a database with the given name. To use this
statement, you need the CREATE privilege for the database. CREATE
SCHEMA is a synonym for CREATE DATABASE as of MySQL 5.0.2.
PostgreSQL supports schemas, which is a subset of a database:
https://www.postgresql.org/docs/current/static/ddl-schemas.html
A database contains one or more named schemas, which in turn contain
tables. Schemas also contain other kinds of named objects, including
data types, functions, and operators. The same object name can be used
in different schemas without conflict; for example, both schema1 and
myschema can contain tables named mytable. Unlike databases, schemas
are not rigidly separated: a user can access objects in any of the
schemas in the database they are connected to, if they have privileges
to do so.
Schemas are analogous to directories at the operating system level, except that schemas cannot be nested.
In my humble opinion, MySQL is not a reference database. You should never quote MySQL for an explanation. MySQL implements non-standard SQL and sometimes claims features that it does not support. For example, in MySQL, CREATE schema will only create a DATABASE. It is truely misleading users.
This kind of vocabulary is called "MySQLism" by DBAs.
in MySQL schema is synonym of database.
Its quite confusing for beginner people who jump to MySQL and very first day find the word schema, so guys nothing to worry as both are same.
When you are starting MySQL for the first time you need to create a database (like any other database system) to work with so you can CREATE SCHEMA which is nothing but CREATE DATABASE
In some other database system schema represents a part of database or a collection of Tables, and collection of schema is a database.
Yes, people use these terms interchangeably with regard to MySQL. Though oftentimes you will hear people inappropriately refer to the entire database server as the database.
Simply if you are thinking or discussing about Mysql. Then take a simple answer
"SCHEMA & DATABASE are exactly the same thing, just a synthetic
sugar in mysql."
Just add some more info:
MongoDB also distinguish schema from database.
schema represent the tables, which means the structure of database.
Microsoft SQL Server for instance, Schemas refer to a single user and is another level of a container in the order of indicating the server, database, schema, tables, and objects.
For example, when you are intending to update dbo.table_a and the syntax isn't full qualified such as
UPDATE table.a the DBMS can't decide to use the intended table. Essentially by default the DBMS will utilize myuser.table_a
not like Postgres, SQL server schema is set of database have same thing
but in mysql schema and database it is the same
MySQL does not support the concept of schema. In MySQL, schema and schemas are synonyms for database and databases.
When a user connects to MySQL, they don't connect to a specific database. Instead, they can access any table they have permissions for

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.