Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.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
Php 防止动态SQL中的SQL注入_Php_Mysql_Sql_Sql Injection - Fatal编程技术网

Php 防止动态SQL中的SQL注入

Php 防止动态SQL中的SQL注入,php,mysql,sql,sql-injection,Php,Mysql,Sql,Sql Injection,我早些时候问过这个问题,但不清楚是什么导致了问题的结束,后来在评论中被告知我应该再次问这个问题 我的PHP/MySQL应用程序的一个要求是允许所有用户创建自己的多个数据“视图”。这些视图不是传统的SQL视图,而是由应用程序执行的 例如,用户可以创建视图并提供以下条件: 视图的名称 每页所需的记录 使用下拉菜单显示哪些列 结果的任何过滤器。第一个下拉菜单用于选择列,第二个下拉菜单用于选择运算符(等于、不等于、大于等),然后第三个下拉菜单用于选择要匹配的值,或者用户直接输入要匹配的值 是否应在给定

我早些时候问过这个问题,但不清楚是什么导致了问题的结束,后来在评论中被告知我应该再次问这个问题

我的PHP/MySQL应用程序的一个要求是允许所有用户创建自己的多个数据“视图”。这些视图不是传统的SQL视图,而是由应用程序执行的

例如,用户可以创建视图并提供以下条件:

  • 视图的名称
  • 每页所需的记录
  • 使用下拉菜单显示哪些列
  • 结果的任何过滤器。第一个下拉菜单用于选择列,第二个下拉菜单用于选择运算符(等于、不等于、大于等),然后第三个下拉菜单用于选择要匹配的值,或者用户直接输入要匹配的值
  • 是否应在给定列上对记录进行分组
根据用户的选择,可能需要将各种表连接到查询以支持select、where和group by子句,并且应用程序用于消除存在的重复表连接

用户配置完视图后,会出现一个下拉菜单,允许用户选择所需的视图,并显示相应的结果

通过将用户的选择存储在多个表中,并将结果查询(实际上,我将查询的各个部分存储在不同的列中,以便在初始查询中计算总结果,并在第二次查询中返回正确的结果数)存储在SQL表中,我实现了此功能。请注意,我存储用户的选择只是为了允许他们编辑视图需求,而不是动态创建结果查询(稍后将对此进行详细介绍)

我认识到我必须非常小心,因为这样做很容易受到SQL禁令的影响。例如,我不能只使用PDO转义用户的输入并将其存储在数据库中,然后稍后检索数据并在查询中使用,因为检索数据时,不再转义

为了应对这种风险,我尽可能地将用户输入限制为整数,并尽可能地进行类型转换。如果用户输入的是百分比和美元,我乘以100,将结果转换为整数,然后除以100再存储。有两个过滤器要求在WHERE子句中使用文本作为值,如前所述,转义数据并不足够,相反,我使用的是
$user\u input=preg\u replace('/[^A-z0-9,]/I','','$\u POST['user\u input'])以确保安全

这是实现此功能的公认方法吗?是否有更简单的方法确保用户输入的安全?我之前的帖子指出,永远不应该尝试这种做法,但是,我不知道还有什么其他方法可以做到。我是否应该采取其他措施来防止注射

或者,我不应该在用户保存视图配置时创建查询并将其存储在表中,而是在用户每次选择给定视图时使用用户保存的值动态创建查询。这将对性能产生负面影响,并增加共谋,但我想我可以做到。你会推荐使用这个策略吗


谢谢

你好,我想我明白了

这就是您正在寻找的:

如果你想让它更安全,那就是用户不能在输入中输入html, 在使用上述函数(即mysql\u real\u escape\u string)后使用此函数

现在,所有使用的输入都将保持原样, 如果字符串是“用户输入”,它将保持为“用户输入”,而不会更改为“用户输入”,因此不会替换任何内容,并且仍然安全


注意。

不要使用COOKIES来存储用户首选项,而是读取这些COOKIES并相应地显示SQL数据。我就是这么做的。你必须广泛使用的东西叫做白名单。根据预定义值检查用户输入,无论是列名还是运算符。之后,您可以将生成的查询存储在数据库中。您可以使用mysqli\u real\u escape\u字符串而不是preg\u replace吗?您当然可以多次使用它(一次是在存储用户的查询配置时,另一次是在创建SQL字符串时)。@James:
mysqli\u real\u escape\u string
不会阻止注入。@YourCommonSense我同意白名单是一个选项,并且是我最初已经实现的。您是否建议像我所展示的那样,使用preg_replace(将
用户输入
转换为
用户输入
),或者使用PHP的
ctype_alpha()之类的工具,以每个字符为单位列出白名单
如果无效,哪个函数将返回false?不幸的是,此链接完全不相关。请阅读此处进行解释:我还提到了addslashes()函数,这正是他想要的。坦率地说,在这种情况下,所有这些函数都是一派胡言。
addslashes()
不应用于转义SQL代码。它不是为该任务而设计的,也不适用于该任务。我建议您阅读经典,以找到更好的替代方案。@lvaroG.Vicario您引用的文章不能为我的需要提供有效的解决方案。请阅读我的原始文章以了解原因。
$safestring=mysql_real_escape_string($_POST['user_input']);
$safestring=addslashes($safestring);
$safestring=htmlspecialchars($safestring);