Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.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注入、实数转义字符串和带引号的查询_Php_Mysql_Sql Injection - Fatal编程技术网

Php SQL注入、实数转义字符串和带引号的查询

Php SQL注入、实数转义字符串和带引号的查询,php,mysql,sql-injection,Php,Mysql,Sql Injection,首先-我知道准备好的声明是“银弹”,我“应该使用它们”-但是对于这个项目,它是不可行的。相信我,我说这不会发生。所以,在布道开始之前……;) 所以,我今晚已经阅读了4个小时的SQL注入 对于使用real_escape_string(我正在使用PHP和MySQL)的每一次反驳都说,基本上,real_escape_string不会阻止这一点: SELECT * FROM something WHERE id=1 or 1=1; 对。明白了 但自从15年前我第一次接触mysql以来,我编写的每个查询

首先-我知道准备好的声明是“银弹”,我“应该使用它们”-但是对于这个项目,它是不可行的。相信我,我说这不会发生。所以,在布道开始之前……;)

所以,我今晚已经阅读了4个小时的SQL注入

对于使用real_escape_string(我正在使用PHP和MySQL)的每一次反驳都说,基本上,real_escape_string不会阻止这一点:

SELECT * FROM something WHERE id=1 or 1=1;
对。明白了

但自从15年前我第一次接触mysql以来,我编写的每个查询都会引用我在查询中发送的所有参数。比如,如果我不使用单引号参数,我会有这样的感觉:查询将失败。所以我总是引用单引号。全部的这个时间

以及:

这怎么可能被打破呢?可以吗?我从来没有看到过一个例子,它击落了不使用无引号版本的real_escape_字符串

在引号里。所有可能脱离引用的内部引用都被转义

再说一遍:我知道事先准备好的陈述是最好的。这不是我要问的。我在问我上面写的东西是否能被破坏


我没有办法。

我相信你的代码是安全的。由于您已将字符串用引号括起来,因此将
解释为SQL关键字的唯一方法是让输入包含一个结束引号。但是
real\u escape\u string
将对此进行转义,因此它不会结束字符串

对于要求为整数的值,您还可以执行以下操作:

$clean = (int)$_POST['userinput'];

这将把输入的
1或1=1
转换为
1
对整数使用
intval()

撇开复杂的漏洞不谈,如果你没有使用预先准备好的语句,那么项目中的任何程序员只要犯一个错误,你就会被套住。在业务环境中,这严重限制了可以投入项目的程序员数量,并使每个查询的质量控制成为绝对必要的


<>如果你计划放大,认真考虑重写你所有的查询;您甚至可以在使用最新技术和mysql增强功能的同时提高性能,因此这并不是完全的损失。

事实上,prepared语句不是一项功能,而是一项原则。一个人可以自己实现它。你必须这样做,而不是设计借口

格式化字符串文字的想法是正确的。然而,这种格式化必须通过预先准备好的语句来完成

您正在使用的手动格式是分离的,可以分离。你在一个地方加引号,在另一个地方转义引号——这本身就是许多灾难的根源。即使您将其移动到一个地方,您的格式仍然是可分离的,这意味着它可以移动到远离实际查询执行的某个地方,并被遗忘在那里

这就是为什么您应该始终使用占位符来表示查询中的变量,然后在替换时格式化数据


这就是为什么我们准备了一个银弹,而不是因为刚才有人告诉过你。操作码是“安全的”。
real\u escape\u函数
识别输入字符串中的“危险”字符,并返回要包含在SQL语句中的“安全”字符串,如果这也是以“安全”的方式完成的,如OP示例中所示,则将其括在SQL文本中的单引号中。或者通过使用
(int)
强制转换为int来避免函数调用,如果您有心情进行微优化,那么您就不会使用PHP;-)我总是把INT传递给INSERT,或者选择单引号,没有问题。它总是有效的。引用它是否存在性能问题?IE:为什么要将其转换为int并取消其引号?如果不使用magic_引号,也不转义输入,也不将其转换为整数,那么它很容易受到sql注入的影响。我已经阅读了准备好的语句,它们实际上会减慢查询速度,除非您反复运行同一个查询。这适用于一个数据库繁重的web应用程序,其中页面加载、执行许多不同的sql查询(不重复任何查询),然后退出。显然,一旦页面加载停止,就无法使准备好的语句保持“活动”。那么性能改进在哪里呢?哦,我之前读过这篇文章——这基本上只适用于使用旧版本的MySQL和/或使用一些非标准字符集的情况。我永远不会将我的字符集设置为GBK,我的MySQL是现代的,所以这不是问题。事实并非如此,一个不会从参数查询中看到性能提高的应用程序是极不可能的。以下是一些文章:这些文章是否相关/正确?那些文章已经有8年历史了。我读过的所有东西都说,如果只使用一次,准备好的语句会慢一些——它们是为重复使用而设计的。一次性陈述总是比只使用一次准备好的陈述要快。谢谢我说我不想听的演讲。
$clean = (int)$_POST['userinput'];