使用MySQL进行SQL注入攻击,这是否符合基线要求?

时间:2011-09-14 10:04:02

标签: php mysql security mysqli sql-injection

我有一个单页面应用程序,浏览器在其中完成所有逻辑工作。除了初始加载,服务器几乎是数据库的奇特接口。

例如,浏览器发送数据字典键,列名/值对以及SELECT的where子句。服务器将部件组装成SQL,执行查询和回复。新功能:例如,在SELECT中,表名和列是从数据字典中提取的 - 浏览器提供数据字典键和SELECT where子句。

这种非常开放的环境非常容易受到SQL注入攻击。目标是防止受到攻击的伤害

要克服的问题

首先,作为discussed,不可能对随机SELECT where clause进行参数化 - SELECT不能使用预处理语句。

其次,mysqli,MySQL的参数化语句库,不支持NULL或MySQL函数,例如CURRENT_DATE或NOW(),discussed

提议的解决方案

首先,如果SELECT无法进行参数化,则由没有DML或DDL权限的用户执行SELECT。这将防止SQL注入攻击更改数据库。

其次,为mysqli编写一个包装函数,允许NULL和MySQL函数作为参数传递。这将允许参数轻松用于所有DML。

第三,影响普通查询或普通用户无法看到或触摸的高度敏感数据。这会将敏感数据(如密码)置于攻击范围之外。

Forth,编写一个包装器命令来强制执行用户/查询类型关系。这将确保SELECT由select用户执行,例如

这项工作的结果是here。从逻辑上讲,问题是这种方法能否成功地防止SQL注入攻击?

非答案答案

我提出了同样的问题before。由于我的演讲工作不佳,收到的答案和评论最终都集中在虚假问题上,而不是解决(诚然)难题 - 这实际上有用吗?

作为参考,以下是其中一些评论和答案。

使用PDO准备好的陈述

首先,预编译语句不能用于所有SELECT - PDO如何帮助?其次,mysqli不接受NULL或MySQL函数 - PDO如何帮助?

为什么重新发明轮子

如果您知道克服这些问题的方法,我真的很想知道 - 这是一个难题。

看不到mysql_real_escape_string()

在传递给数据库查询函数之前,应该对值进行清理mysql_real_escape_string()是可用的一组消毒功能之一,例如,可以使用不同的消毒剂来保存日期。

工作太多

请与我分享您对克服这些问题的任何方法的了解 - 我真的希望有更好的洞察力。也就是说,从我再次设置整个事情,按照我的笔记花了30到45分钟。此后没有花费时间。

我对mysqli

感到满意

当您无法参数化SELECT时,如何防止SQL注入攻击?你期望在更新列时永远不会使用NULL吗?每个男人都有自己的毒药,但这些都是我希望解决的问题 - 不能与之共存。

@Konerack指出有限数量的参数

右。更改为使用eval()(shudder)解决问题的代码。需要安全审查。

问题再次

这种方法是否可以防止SQL注入攻击,同时克服没有参数化SELECT和mysqli参数限制的问题?

1 个答案:

答案 0 :(得分:1)

答案很简单:

对于参数,请使用PDO或mysql_real_escape_string()

对于其他动态SQL(表名,列名,语法元素),请使用白名单。

请参阅:How to prevent SQL injection with dynamic tablenames?

您不能相信浏览器会保持在Javascript中设置的范围内。这很容易操作。因此,您必须将该端的所有数据视为不可信。确保根据允许的关键字列表检查where子句中的所有元素。

为此您将使用:

  1. 检查符号白名单:=, <>, >, LIKE, NULL, IS
  2. 针对布尔运算符的白名单进行检查:AND, OR, XOR, NOT
  3. 所有值必须正确包含在单个'引号中,您需要通过mysql_real_escape_string()提供这些值,以确保没有恶作剧。
  4. 不在(1,2)中且未包含在单引号中的所有值都是列名,请根据允许的列名称列入白名单。
  5. 拒绝所有其他输入。