所以我忙于PHP,在我想知道时将数据插入到mysql中:我发现有些帖子说使用单引号将数据插入数据库是不好的做法。其中一个例子:Why are VALUES written between quotes when sent to a database? 帖子是关于他们为什么写在引号之间的,但有一件事是清楚的:插入它是不好的做法:
$sql = INSERT INTO example (example1, example2, example3) VALUES
('$example1', '$example2', '$example3');
为什么这是不好的做法?显然,如上面给出的链接所述,注射是难受的。 OP他的问题与评论有关:我们使用mysqli_real_escape_string
。给出的责任是:
@XX在很大程度上,是的,它是解决问题的另一种方法。它不会禁用任何东西,但它会逃避事情,例如在SQL字符串中“变为”或“,”使攻击者不会结束字符串。有一些尴尬的情况,这种逃避很难,并且很容易错过许多逃生呼叫,这就是为什么参数化查询被认为是最可靠的方法。
首先:脚本如何欺骗mysqli_real_escape_string
以逃避某些东西?如果我错了,我发现了以下内容并说明了我:mysqli_real_escape_string - example for 100% safety。你可以看到他引用了另一个页面,它有一个答案。然而,他随后声称应该使他的数据100%安全,其他人回应:
是的,这通常是安全的。正确使用时,Mysql和mysqli是完全安全的(尽管有非常特定的编码,但特定的错误)。准备好的陈述的优点是以错误的方式做事情更加困难。
我有以下示例为自己说清楚:我有两扇门,一扇门打开,但是在一扇关闭的门后面。你怎么会在门前关上一扇敞开的门??
这里有一个答案:SQL injection that gets around mysql_real_escape_string(),但他说是一个安全的例子:
mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");`
mysqli_real_escape_string
是不是已经做了同样的事情?他只是指定了哪些字符mysqli_real_escaped_string
。那么这一切突然变得如此安全呢?因为它与你说的完全相同:
$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);
那怎么做:
mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");
变得安全了,这个:
$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);
不?他不只是缩小mysqli_real_escape_string
会逃脱的东西,从而使其更加脆弱吗?
答案 0 :(得分:1)
问题是,mysqli_real_escape_string()或其他正确的转义实际上在技术上是安全的,最后,这也是关于参数化查询的内容。然而,总有一个。例如,只有在变量周围有引号时它才是安全的。没有引号它不是。当它与一个开发人员进行1000线项目时,在前3个月可能没问题。然后最终甚至一个开发人员会忘记引号,因为它们并不总是需要语法。想象一下,在5年之后,在拥有200个开发者的200万LOC项目中将会发生什么。
同样,您绝不能忘记使用手动转义功能。这可能很容易。然后有一个经过验证的变量,只能保存一个数字,因此您可以确定只需将其放入而不进行转义即可。然后你改变主意并将其改为字符串,因为无论如何查询都是正确的。或者其他人在2年后做到这一点。等等。这不是技术问题。这是一个管理问题,从长远来看,你的代码会以某种方式受到攻击。因此这是不好的做法。
另一方面,如果手动转义到位,则自动扫描SQL注入漏洞要困难得多。静态代码扫描程序可以轻松找到连接查询的所有实例,但如果有任何问题,它们很难将先前的转义关联起来。如果使用参数化查询之类的东西,可以直接找到sql注入,因为所有连接都是潜在的候选者。
答案 1 :(得分:0)
设置连接的字符集不会改变mysqli_real_escape_string()
转义的内容。但它避免了多字节字符错误,因为它控制了插入反斜杠转义字符后字符串的解释方式。
当然,您可以通过using query parameters instead避免任何不确定性。