哪个查询更安全?
我甚至听说过 salt();和php5中的md5(); 对于mySQL插入来说是非常安全的。
$customers_email = mysql_real_escape_string(trim(strtolower($_REQUEST['customers_email'])));
$customers_email = mysql_real_escape_string(($_REQUEST['customers_email']));
或者甚至是这个,我想到了:
$1=$_REQUEST['customers_email'];
$2=$1;
$3=$2;
$4=$3;
$5=$4;
$a=$5;
$xx = mysql_real_escape_string(($a));
我的原帖:https://stackoverflow.com/questions/7633993/php-mysql-select-how-to-make-it-secure
答案 0 :(得分:3)
之前已经多次询问过这个问题。
最好使用PDO,但是如果你必须使用mysql_ * lib,那就这样做:
转义参数
以下代码是100%安全的:
$var = mysql_real_escape_string($_POST['var']);
$query = "SELECT * FROM table1 WHERE afield = '$var' "
// You must quote your $vars ^ ^
// failure to do so defeats the escaping and causes syntax errors.
不需要进一步的操作来使代码SQL注入相同。
转义动态列/表名称
这段代码:
不安全,无法使用
$afield = mysql_real_escape_string('$_POST['var']);
$query = "SELECT * FROM table1 WHERE `$afield` = 1 "
//You can only use escaping for values, never for dynamic SQL.
这不起作用,您需要针对白名单检查数据库,表和列名称。
动态SQL 100%安全
$allowed_fields = array('field1', 'field2');
$afield = $_POST['afield'];
if (in_array($afield, $allowed_fields)) {
$query = "SELECT * FROM table1 WHERE `$afield` = 1";
}
关于哈希和腌制
您只使用盐渍哈希作为密码
将未加密的密码存储在数据库中是一个坏主意,而不是存储散列密码
为了打败彩虹表,你必须用不同的半随机盐来加盐。盐不需要保密,只需要有点随机。
//To add a user.
INSERT INTO users (name, salt, passhash)
VALUES ('$username', '$salt', SHA2(CONCAT('$salt','$password'),512));
//To check a password:
SELECT u.id FROM users u
WHERE u.name = '$username'
AND passhash = SHA2(CONCAT(salt, '$password'),512);
//To change a password:
UPDATE users u SET passhash = SHA2(CONCAT(s.salt, '$newpassword'),512)
WHERE u.id = (SELECT u2.id FROM (
SELECT u1.id FROM users u1
WHERE u1.name = '$username'
AND passhash = SHA2(CONCAT(u1.salt, '$oldpassword'),512) u2) s
另见:
How to prevent SQL injection with dynamic tablenames?
How does the SQL injection from the "Bobby Tables" XKCD comic work?
How can I prevent SQL injection in PHP?
答案 1 :(得分:3)
您的查询都不比其他查询更安全。其中一个将字符串转换为全部小写并修剪空格。这对阻止SQL注入没有任何作用。您的上一个查询与普通mysql_real_escape_string($_REQUEST['customers_email']);
相同。
答案 2 :(得分:2)
您的每个第一种方法都是相互安全的,因为它们使用的是mysql_real_escape_string
函数。 SQL注入通过在您的字符串中引入额外的引号来突破您的条件来“突破”您的查询。
考虑:
$email = $_GET['email'];
$sql = "SELECT * FROM users WHERE email='$email'";
如果攻击者在字符串插值后将提交' OR 1=1 --
您的查询的电子邮件:
$sql = "SELECT * FROM users WHERE email='' OR 1=1 -- '";
在这种情况下,MySQL中的双短划线是评论,评论我们原来的正确引号。通过运行mysql_real_escape_string
,数据库引擎将正确地转义电子邮件字符串,以防止其中的引号标记“突破”您的查询。
每个数据库引擎的确切转义样式是不同的,因此每个引擎都有自己的转义函数集。出于这个原因,明智的做法是转而使用其他人在此处提到的PDO和预备语句。
我希望这进一步解释了这一点。