我只是不明白。准备好的语句如何比未准备的获取数据的语句更安全。我不是在谈论写入数据库,只是提取数据。我无法看到userFname和userLname如何比userEmail和userPassword更安全。提前谢谢。
$stmt = $mysqli->stmt_init();
if ($stmt->prepare("SELECT userFname, userLname FROM users WHERE userEmail = ? and userPassword = ?")) {
$stmt->bind_param("ss", $userEmail, $userPassword);
$stmt->execute();
$stmt->bind_result($userFname, $userLname);
while ($stmt->fetch()) {
//Remember first name, last name, and email
$_SESSION['Email']=$userEmail;
$_SESSION['Fname']=$userFname;
$_SESSION['Lname']=$userLname;
$stmt->close();
//go to dashboard page
header ("location: dashboard.php");
}
$error2="Email and Password do not match, please try again.";
}
答案 0 :(得分:0)
我是MySQL的培训讲师。我告诉一群与会者关于SQL注入的风险,一个人说,“告诉我。”
他递给我他的笔记本电脑,其浏览器打开了他网站的登录界面(实际上它只是它的QA实例)。
对他的代码或他的数据库一无所知,我做了一个有根据的猜测,他有一个类似你的SQL查询,他没有使用查询参数,并且他没有正确地转发输入。我输入了一个用于登录的字符串,包括close-quote和一些布尔表达式,然后我输入了密码的随机击键。
他的应用程序验证了我的虚假登录信息,我在。
我认为向你展示我是如何做到这一点并不合适,但这不是火箭科学 - 你需要的是对布尔代数的最少知识。
但重点是SQL注入SELECT查询可以允许非法操作,就像SQL注入修改数据的语句一样。
重新评论不良信息:
确实不能欺骗查询参数,也不需要使用转义函数。
但查询参数仅适用于通常使用单个字符串,日期或数字文字的地方。查询参数不能用于动态表名,列名,值列表,SQL关键字,表达式等。对于那些,您仍需要在调用prepare之前将应用程序变量插入到SQL查询中(),像老派,不安全的编程。因此,您仍需要小心避免SQL注入漏洞。最好的方法是将列入白名单内容,然后再将其包含在SQL查询中。
有关详细信息,请参阅我的演示文稿SQL Injection Myths and Fallacies,或webinar of me presenting it(免费,但需要注册)。我还在我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming的一章中写了关于SQL注入的文章。
答案 1 :(得分:0)
在SQL注入领域有一个巨大的巴比伦塔。
每个人都在使用十几个单词,很难理解他们的意思,更糟糕的是,他们对意义有了自己的想法。
示例: 99%的PHP用户会告诉您数据必须“转义”。虽然技术上逃避是一种非常特殊的行为,但 不足以保护一个案件,而无用,而另一个案件则有害。
“清理”,“过滤”,“逃避”,“准备好的陈述”等列表中的每一个字都是如此。
因此,形象地说,每次谈话都会变成盲人和聋人之间的争执。
完全相同的适用于名为"input input"
的内容。这是另一个令人困惑的问题的根源 - 更糟糕的是 - 漏洞。虽然,最明显的意思是它与SQL注入完全无关。。
因此,阅读各个网站的建议时请记住,您必须了解术语,并且 - 不仅如此 - 了解作者的意思。
回到你的问题,答案很简单:
这些规则记忆起来相当简单。所以 - 不要在其中添加任何复杂性!不要因为“这些数据来自何处?”这样的问题而烦扰自己。 “它在哪个查询中?” - 它们毫无用处且容易出错。
遵循这些规则并不容易,但这是另一个主题。