Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL 5.5中的一次性只读SQL语句验证?_Mysql_Sql - Fatal编程技术网

MySQL 5.5中的一次性只读SQL语句验证?

MySQL 5.5中的一次性只读SQL语句验证?,mysql,sql,Mysql,Sql,我有一个接口,我想允许输入任意的SQL select语句(作为输入字符串),该语句将从给定表中选择数据以用于操作。我希望确保此语句不会对数据库进行更改 string query = GetStringFromForm(...); DatabaseStatement statement(query); statement.execute(); while (statement.fetch(...)) ... 实现这一点的一种方法是创建一个具有适当权限的新数据库用户,然后在该用户下执

我有一个接口,我想允许输入任意的SQL select语句(作为输入字符串),该语句将从给定表中选择数据以用于操作。我希望确保此语句不会对数据库进行更改

string query = GetStringFromForm(...);

DatabaseStatement statement(query);

statement.execute();

while (statement.fetch(...))
    ...
实现这一点的一种方法是创建一个具有适当权限的新数据库用户,然后在该用户下执行该语句。这将是一个麻烦,因为它需要设置这个新用户并为其创建一个新的数据库连接等等


有没有办法隔离一条语句MySQL 5.5的权限?或者其他方法来实现这一点?

不要使用与所有内容相同的登录名连接到数据库

至少您应该使用电子登录来实现此架构:

  • 用于创建表等的开发级登录
  • 应用程序用来运行应用程序的登录名
  • 用于执行用户指定查询的登录名
  • 这意味着您的应用程序登录仅具有它所需的权限—对表进行必要的读写,而不是对每个表进行所有操作;例如,应用程序登录不需要能够创建或删除表

    这不仅限制了代码错误的影响,还限制了有人入侵您的系统的范围(例如SQL注入攻击)

    这还意味着运行特定于用户的查询的登录只需要被授予SELECT权限,并且只需要被授予它应该能够使用的表/视图/函数。如果他们试图运行他们没有权限的插入或删除操作,您可以捕获错误并告诉用户他们是一个
    非常淘气的男孩
    -记住,RDBMS不会让用户损坏您没有授予他们权限的任何操作


    简而言之,RDBMS已经有了登录权限体系结构。使用这些来限制代码不同方面的权限和功能

    我不会试图重新发明这个轮子。极有可能是您遗漏了一个技巧或黑客,它暴露了应用程序中的漏洞。我很感激你说这很麻烦,但这确实是正确的做事方式,也是唯一可靠的做事方式。抱歉,这是数据安全的标准方法,这是有原因的


    (请相信我,即使没有人试图入侵您的系统,最终也会有人意外地在-中键入一些古怪的查询,绕过您的安全设置,对您的数据库进行恶意攻击。)

    使用MySQL 5.6,您可以做到:

    START TRANSACTION READ ONLY;
    


    我想这正是您想要的,但您必须升级到5.6才能使用它。

    麻烦?这可能比在此处发布问题所需的时间要短;-)麻烦主要是新的数据库连接,它当前使用一个对上层透明的全局连接池(每个线程一个),因此需要绕过它。更好的方法是使用一个命令,以某种方式临时限制当前数据库连接的权限。在我们的体系结构中,当前将数据放入数据库语句的唯一方法是通过准备好的查询(都是字符串文本)中的占位符
    (?)
    ,就我所知,这让我们对注射攻击免疫,对吗?占位符不能接受任意SQL,对吗?因此,执行错误语句的唯一方法是程序员在代码中键入错误语句,这在开发级别登录时同样容易<代码>选择1作为虚拟);从aTable中删除
    真的会破坏你的查询。这正是容易受到SQL注入攻击的情况。这不会插入带有占位符的准备好的查询中。该字符串将被有效地“转义”为带引号的字符串。任何可能包含要执行的SQL的字符串都可能被滥用。如果将其作为字符串参数提供,则无法执行。如果它是作为动态SQL的替换部件提供的,则可能会被滥用。如果没有完整的SQL解析器和权限控制机制,它可能被滥用。如果你不相信这一点,创建一个网站,并要求用户攻击它…是的,当然。这就是为什么我们的体系结构不允许“动态SQL”,因为它容易受到SQL注入攻击。所有SQL查询都是带有占位符的字符串文字,不易受到SQL注入攻击。