【发布时间】:2011-11-16 21:19:33
【问题描述】:
我有一个单页应用程序,浏览器在其中完成所有逻辑工作。除了初始加载之外,服务器几乎是一个漂亮的数据库接口。
例如,浏览器发送数据字典键、列名/值对以及 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。
第三,隐藏高度敏感的数据,普通查询或普通用户无法看到或触及这些数据。这会将敏感数据(例如密码)置于攻击范围之外。
第四,编写一个包装顺序来强制执行用户/查询类型关系。这将确保 SELECT 由select 用户执行,例如
努力的结果是here。从逻辑上讲,问题是这种方法能否成功防止 SQL 注入攻击?
未回答的答案
我提出了同样的问题before。由于我的演示工作不佳,收到的答案和 cmets 最终专注于虚假问题,而不是解决(公认的)困难问题 - 这真的有效吗?
作为参考,以下是其中的一些 cmets 和答案。
使用 PDO 的预处理语句
首先,准备好的语句不能用于所有 SELECT - PDO 有什么帮助?其次,mysqli 不接受 NULL 或 MySQL 函数——PDO 有什么帮助?
为什么要重新发明轮子
如果您知道克服这些问题的方法,我真的很想知道 - 这是一个难题。
看不到mysql_real_escape_string()
值应该在传递给数据库查询函数之前进行清理。 mysql_real_escape_string() 是一组可用的消毒功能之一,例如,可以对日期使用不同的消毒剂。
工作量太大
请与我分享您对克服这些问题的任何方法的了解 - 我真的希望有更好的见解。也就是说,从我重新设置整个东西开始,按照我的笔记花了 30 到 45 分钟。此后不会产生时间成本。
我很高兴mysqli
当您无法对 SELECT 进行参数化时,您将如何防止 SQL 注入攻击?您是否希望在更新列时从不使用 NULL?每个人都有自己的毒药,但这些都是我希望解决的问题——而不是忍受。
@Konerack 指出参数数量有限
没错。更改为使用解决问题的eval()(不寒而栗)的代码。需要安全审查。
又是一个问题
这种方法能否在克服无参数化 SELECT 和mysqli 的参数限制的问题的同时防止 SQL 注入攻击?
【问题讨论】:
-
Will this approach protect against SQL Injection Attacks?不,不会。 -
@Johan - 如果它不能保护,我很想听听一个具体的例子,这样我就可以理解它了!
-
我不知道为什么,但是让浏览器发送动态表/列名是一个糟糕的主意。我不知道您要解决的问题是什么,但这似乎是错误的方法。
-
@N.B. - 所有工作在浏览器中完成!例如,在与用户交互时,浏览器知道我们需要一个员工列表,其中这个和那个。它要求服务器检索它。
-
那又怎样?浏览器告诉您的服务器“调用存储过程以检索用户数据”而不是“嘿,从
where 中选择 x、y、z”有什么问题?我很抱歉这么说,但你采取了错误的方法。最后,浏览器必须知道它需要发送什么表/列/where子句。因此,它不再需要知道应该调用什么过程来获取相同的数据。你的设计方法是错误的,你看到了一个巨大的限制——清理数据和暴露你的结构。
标签: php mysql security mysqli sql-injection