最初我使用mysql_connect和mysql_query来做事。然后我学习了SQL注入,所以我试图学习如何使用预处理语句。我理解PDO类的准备和执行函数如何有助于防止SQL注入。
但是,只有在用户输入存储到数据库中时才需要准备语句。还是可以继续使用mysql_num_rows,因为我真的没有冒这个功能被黑客入侵的风险吗?或者使用预准备语句来执行此操作更安全吗?我是否应该为涉及使用mysql的所有内容使用预准备语句?为什么呢?
我真的很感激任何答案和反馈。谢谢。
答案 0 :(得分:34)
<强> TL / DR 强>
mysql_*
个函数。 (Notice the big red box?)
警告此扩展程序在PHP 5.5.0中已弃用,已被删除 在PHP 7.0.0中。相反,MySQLi或PDO_MySQL扩展应为 用过的。另请参阅MySQL: choosing an API指南和related FAQ了解更多信息 信息。该功能的替代方案包括:
您最好使用PDO
或MySQLi
。使用预准备语句时, 2
中的任何一个都可以作为兼容库。
信任用户输入而没有准备好的陈述/消毒它就像把车停在一个不好的街区,解锁并点着钥匙。你基本上是在说,只是来看看我的好东西
你应该从不,我的意思是永远不要相信用户输入。除非你想要这个:
在参考数据并存储它时,如评论中所述,您可以从不,并且绝不应信任任何与用户相关的输入。除非您确信用于操作所述数据库/值的数据是硬编码到您的应用程序中,否则您必须使用预准备语句。
现在说明为什么要使用预准备语句。这很简单。要防止SQL注入,但要以最直接的方式实现。预备语句的工作方式很简单,它将查询和数据一起发送,但是分开(如果有意义的话哈哈) - 我是什么意思是:
Prepared Statements
Query: SELECT foo FROM bar WHERE foo = ?
Data: [? = 'a value here']
与其前身相比,您使用数据截断查询,将其作为整体发送 - 反过来,这意味着它作为单个事务执行 - 导致SQL注入漏洞。
这是一个伪PHP PDO
示例,向您展示预备语句/绑定的简单性。
$dbh = PDO(....); // dsn in there mmm yeahh
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Taken from PHP Manual for PDO Prepared Statements
更多阅读
答案 1 :(得分:3)
TL; DR如果您的应用接受任何用户输入,则100%使用准备好的语句
你似乎有点混乱。首先,请don't use mysql_*
; mysql_*
函数已过时,deprecated且不安全。请改用MySQLi
或PDO
。其次,mysql_num_rows
与预准备语句无关,而且无论如何都不是PDO功能。您在运行查询之前准备语句,而不是在您想要计算行数时之后准备语句。
至于何时准备陈述,@ Mike'Pomax'Kamermans在评论中钉了它。如果您曾经使用过任何类型的第三方或第三方应用程序(包括浏览器)生成的用户曾经触及的任何数据(甚至是所谓的可信用户),请使用预先准备好的语句。只有100%的数据是硬编码或完全由您的代码生成(如简单的计数器变量),您才能信任它。
例如,你不能相信:
当然,在将它们放入数据库之前,您应该验证所有这些(例如,检查电子邮件地址是否真的是电子邮件地址)。但即便如此,使用准备好的陈述是安全的方法。
答案 2 :(得分:0)
Mysql_*
已被弃用,以便更好地切换mysqli_*
或PDO
用于防止sql注入(mysql): - How can I prevent SQL injection in PHP?。
准备好的语句(这些是由数据库服务器与任何参数分开发送和解析的SQL语句。)用于每个用户生成的查询数据。
就像发布您使用查询匹配/获取记录到db的数据一样。这意味着当您使用表单数据触发查询时。
答案 3 :(得分:0)
这有两个解决方案 -
01-使用准备好的陈述
为了防止SQL注入,我们必须使用一些名为prepare语句的东西,它使用绑定参数。准备语句不会将变量与SQL字符串组合在一起,因此攻击者无法修改SQL语句。 Prepared Statements将变量与已编译的SQL语句组合在一起,这意味着SQL和变量是分开发送的,变量只是被解释为字符串,而不是SQL语句的一部分。
02-使用mySQLi准备好的语句。
使用以下步骤中的方法,您不需要使用任何其他SQL注入过滤技术,例如mysql_real_escape_string()。这是因为使用预准备语句不可能进行传统的SQL注入。
例如 -
$name = $_GET['username'];
if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) {
// Bind a variable to the parameter as a string.
$stmt->bind_param("s", $name);
// Execute the statement.
$stmt->execute();
// Get the variables from the query.
$stmt->bind_result($pass);
// Fetch the data.
$stmt->fetch();
// Display the data.
printf("Password for user %s is %s\n", $name, $pass);
// Close the prepared statement.
$stmt->close();
}
您可以找到有关此表单的更多信息 - http://www.wikihow.com/Prevent-SQL-Injection-in-PHP