这三个查询在安全性和良好的编码语法方面有什么区别?
查询1$sql = "SELECT user_id,
user_email,
user_pass
FROM user_tb
WHERE user_email ="".$e.""
AND user_pass = md5("".$p."") ";
查询2 $sql = "SELECT user_id,
user_email,
user_pass
FROM user_tb
WHERE user_email = '$e'
AND user_pass = '$p' ";
查询3
$sql = "SELECT user_id,
user_email,
user_pass
FROM user_tb
WHERE user_email = $e
AND user_pass = $p ";
这三个都没有有效的安全性,并且容易受到任何sql注入的影响。你可以在变量周围使用mysql_real_escape_string(),或者使用准备好的语句来保证安全。
话虽如此,在$e和$p变量周围加上引号只会确保在这些值为空的情况下不会出现sql错误。
第一个对变量($e和$p)执行字符串连接,另外使用MD5函数获取密码的哈希值,以便与USER_TB.user_pass
列值进行比较。如果值没有作为散列存储,MD5就没有任何用处——因为没有任何东西可以匹配。
第二个示例缺少MD5函数的使用,但是在单引号中适当地将变量括起来,以便与列值进行比较时将其视为字符串字面值。
第三个查询缺少用于正确处理SQL字符串的单引号,并且使用MD5函数。
总结这三个都容易受到SQL注入攻击。如果不使用PDO, sprintf是使用预处理语句的解决方案:
$query = sprintf("SELECT t.user_id,
t.user_email,
t.user_pass
FROM USER_TB t
WHERE t.user_email = '%s'
AND t.user_pass = '%s'",
mysql_real_escape_string($e),
mysql_real_escape_string($p));
$result = mysql_query($query);
在我的书中它们都失败了,除非$e
和$p
都已经在屏幕外进行了消毒。如果是这样的话,那么第2条就胜出了。MD5是一个弱散列。与MySQL相比,PHP可以使用hash_hmac()
sha512或其他库(每个人都会有这样的说法)执行更强的哈希。如果你不顾一切地使用md5()
,我可以想象php在这里会比MySQL执行得更快,但这不是安全问题。除此之外,#1和#2是并列的。
#3的问题是,由于某种原因,$e或$p可能为空。你的查询将是where user_email= AND user_pass
,你会得到一个讨厌的MySQL语法错误。除了他们可能得到的其他卫生条件外,他们还需要用引号括起来,否则卫生条件对你没有任何好处。
编辑:正如OMG Ponies指出的那样,您需要与md5()(或任何散列)检查保持一致性。这是我的假设,密码哈希存储和查询#2和#3上面,$user_pass
是由php哈希在查询中使用之前。
我也喜欢"查询2"。它的安全性为0,这很容易受到sqlinject的攻击。
您应该对$e和$p字符串进行消毒,并确保它没有像+/*——' "等坏字符