我使用大量公共代码组合了一个FiveM服务器,并发现存在允许用户破坏或删除底层数据库的作弊系统。原因是他们可以注入包含DROP, DELETE, INSERT和UPDATE的Lua脚本,如果他们知道模式可能会做任何他们喜欢的事情。
我的意图是拒绝访问除SELECT以外的所有命令,并将所有其他逻辑移到存储过程中。问题是,执行进程的用户将是游戏用户帐户,如果锁定,也将被阻止服务器端?我是否能够拒绝调用应用程序的访问,但允许从存储过程中访问,或者让进程作为不同的帐户执行,而不是普通的SELECT语句?还有其他可行的考虑或设计吗?我将在所有调用中使用参数来帮助防止注入,但我对MySQL相当陌生,所以想知道人们在这些情况下采取了什么其他步骤。
是的,你可以给MySQL用户只调用过程的权限。然后,过程以定义该过程的用户的权限执行。
阅读https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html关于SQL SECURITY
有DEFINER
或INVOKER
选项的部分。默认为DEFINER
,这是您想要的。
然而,你还需要拒绝应用程序用户的SELECT权限。恶意用户可能只使用SELECT权限就会造成问题。它们不能更改数据,但会使数据库服务器过载。
因此,您需要在存储过程集合中实现每个数据库查询,包括读和写。
这里有一个替代建议:允许应用程序像今天一样工作,应用程序使用其用户名连接并直接执行SQL查询。
但是如果用户想要调用他们的Lua脚本,只允许在一个单独的数据库连接上,使用一个具有有限权限的不同的MySQL用户。基本上只有特定模式上的EXECUTE
特权。您可以实现一组允许Lua脚本运行的存储过程,并将它们放在该模式中。那么Lua脚本就不能完成应用程序所做的其他任务,Lua脚本只能运行你想让它们运行的有限过程集。