Restricting commands to procedure only in MySQL / MariaDB - mysql

I've put together a FiveM server using alot of public code and discovered there are cheat systems out there that allow the user to corrupt or delete the underlying database. The reason is because they can inject Lua scripts which can contain DROP, DELETE INSERT and UPDATE and if they know the schema potentially could do whatever they like.
My intention is to deny access to every command except for SELECT and move all the other logic to stored procedures. The thing is that the user executing the proc will be the game user account which if locked out would also be blocked server side? Am I able to deny access from calling applications but allow access from within a stored procedure or have the procs execute as a different account vs the normal SELECT statements? Are there any other considerations or designs that could work? I'll be using parameters across all calls to help guard against injection, but I'm fairly new to MySQL so wondering what other steps people take for these scenarios.

Yes, you can give the MySQL user privilege to call procedures only. Then the procedures execute with the privileges of the user who defined the procedure.
Read https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html the parts about SQL SECURITY which has choices DEFINER or INVOKER. The default is DEFINER, which is what you want.
However, you would also need to deny SELECT privilege to the app user. A malicious user can cause problems with nothing but SELECT privilege. They can't change data, but they can overload the database server.
So you'd need to implement every database query, both reads and writes, in a collection of stored procedures.
Here's an alternative suggestion: Allow the app to work as it does today, where the app connects using its username and does SQL queries directly.
But if the user wants to invoke their Lua script, only allow that on a separate database connection, using a different MySQL user with limited privileges. Basically only the EXECUTE privilege on a specific schema. You can implement a set of stored procedures that the Lua script is allowed to run, and put them in that schema. Then Lua scripts cannot do other tasks that the app does, a Lua script can only run the finite set of procedures you want to allow them to run.

Related

How to create a stored routine that is editable from everywhere

I am practising creating MySQL stored routines and am having problems editing them from different areas. If I create it in HeidiSQL, the definer is saved with the IP address so can only edit them in HeidiSQL from the same IP. If I create them in phpMyAdmin, it is only editable from phyMyAdmin, not HeidiSQL.
When you bear in mind that I can edit the actual table data (create, delete, drop, etc) from anywhere (if I have added the IP address), it seems ludicrous that these limitations occur with what is essentially a simple function.
Is there any way, when creating a stored routine, I can set the definer so that it is accessible from whatever program and IP address I am using?
You need to grant alter routine privilege to your users on either database or global level using the grant statement. This way they can edit each other's stored procs. Both heidisql and phpmyadmin provide GUIs for changing privileges.
Apparently, you did not properly set up the users' privileges, so no reason to blame mysql.

GoDaddy cPanel SHOW CREATE PROCEDURE Permissions After Logout

I am attempting to recover statements within procedures in a MySQL database. It seems that when using cPanel through GoDaddy, the user changes when logging in through PHPMyAdmin, resulting in the 'definer' of a procedure being different than the current user after a single logout. This seems to prevent SHOW CREATE PROCEDURE from returning a proper CREATE statement due to permissions.
A workaround is perhaps defining a user and using the account in defining procedures. While not desirable, it may be sufficient.
Is there any way to recover the existing procedures?
A backup of the database may be performed through cPanel, which includes the procedures.

Good security in MySQL web application: Root? Not Root?

Suppose you're writing a simple database web application using Ruby and MySQL. Access to the database is controlled by Ruby code. The user name that the Ruby code uses to access the data is the only regular user on the database. Does it make sense for that user to be "root"? Or is there any extra security in creating a second user just for the application?
Simple, consider the root as the main user, who can do everything (by default).
If he wants to dump the whole database, he can, if he wants to create some data to create (for example) fake account to overpass your bank system, he can.
So if your code is not enough secure (and this is quite often usually), you have strong security issue.
Usually, "a basic" security (really basic), should looks like that :
create a simple user, give him (with GRANTS) the right to SELECT, INSERT, UPDATE and DELETE on a specific database.
create another user who can SELECT and lock tables and SHOW VIEWS to perform dump (database save).
On a more "complex" system, you should create many users, depending of what they should access, this is for simple reason : if somebody got a SQL injection access, if the user can only access to a single view (for example), and not the whole database, this is a security issue but not the baddest one...
Also view are often used for that...
And finally don't forget triggers if you want (for example a log table), to disable insert or update or delete on a table, for everybody (except somebody who can destroy trigger of course) :
Use a trigger to stop an insert or update
Besides editing or deleting all data in your database, the root user also have the FILE privilege which gives access to:
LOAD DATA INFILE which can be used to read any file on the server machine.
LOAD DATA LOCAL INFILE which can read files on the client machine (the web server machine).
SELECT ... INTO OUTFILE which can create files on the server machine.
This is why your application should have only the privileges it needs, and this is also the reason your MySQL server daemon should be run as a non-privileged user on the server machine.
See also General Security Issues in the manual.
If everybody/thing is root, you lose auditability, you lose the ability to restrict the app to stop attacks (i.e. your app doesn't need this segment of sensitive information, seal it away from its user). If somebody compromises the app, you can suspend the account etc.
I would not make a user "root".
I'd create a separate username and password just for that application and GRANT it only the permissions required to do its job.
I would create a new user, giving it only the permissions it needs (SELECT, UPDATE, INSERT and DELETE usually do the trick). Like that, you limit the ability for the code to be manipulated in an unintended way.
"root", or generally speaking, users with Super User privileges, can change passwords, delete accounts, and therefore prevent you from accessing your own database.
If you server hosts only one application, then you may not need to create several lesser privileged accounts. However, it is common practice to create at least one user for each application, so that if one application gets compromised, other applications (and underlying data) may not be.

How to include a .sh (script) file in Mysql stored procedure?

Is it possible to include a Script file (.sh file) inside a stored procedure in Mysql?
If yes, then how?
And if no, then why?
Like #mu is too short said:
You need to install these UDF's from: http://www.mysqludf.org/lib_mysqludf_sys/index.php
Here's the download link: http://www.mysqludf.org/lib_mysqludf_sys/lib_mysqludf_sys_0.0.3.tar.gz
Note that you shell commands will run with the privileges of the MySQL user, not with the privileges of the user that's connecting to MySQL.
For a security point of view this is probably a bad idea.
Note the warning in the link:
A Note of Caution
Be very careful in deciding whether you need this function. UDFs are available to all database users - you cannot grant EXECUTE privileges for them. As the commandstring passed to sys_exec can do pretty much everything, exposing the function poses a very real security hazard.
Even for a benign user, it is possible to accidentally do a lot of damage with it. The call will be executed with the privileges of the os user that runs MySQL, so it is entirely feasible to delete MySQL's data directory, or worse.
The function is intended for specialized MySQL applications where one needs extended control over the operating system. Currently, we do not have UDF's for ftp, email and http, and this function can be used to implement such functionality in case it is really necessary (datawarehouse staging areas could be a case in example).
You have been warned! If you don't see the hazard, please don't try to find it; just trust me on this.
If you do decide to use this library in a production environment, make sure that only specific commands can be run and file access is limited by using AppArmor.

mySql stored procs encryption

I am looking into ways to encrypt mySQL stored procedure source code when installed in clients local environment.
I did lot of research on this topic and had no luck except for one promising reply from gazzang.com
Here is the reply from gazzang. Let me know if someone has already tried this out.
We should be able to encrypt the table where store procs and functions are stored - mysql.proc
Thus os users won't be able to read the contents of the sp or functions.
I can't remember which internal table views are stored in but the same some apply to them.
I am not sure we could come up with a solution to encrypt the routines internal to mysql.
Other databases that do this really implement "obfuscation" internally - I think PostgreSQL does that for example.
You cannot encrypt stored procedures in a really useful way, because MySQL server will have to decrypt it anyway when it reads stored procedure from it's tables. If you encrypt the table file, your customer will login as root and make dump on mysql.proc table using native MySQL statements. If you change root password, they will always have a way to start MySQL with --skip-grant-tables switch to overcome that.