G.S*_*NGH 11 php security sql-injection prepared-statement
最初我使用mysql_connect和mysql_query来做事.然后我学习了SQL注入,所以我试图学习如何使用预处理语句.我理解PDO类的准备和执行函数如何有助于防止SQL注入.
但是,只有在用户输入存储到数据库中时才需要准备语句.还是可以继续使用mysql_num_rows,因为我真的没有冒这个功能被黑客入侵的风险吗?或者使用预准备语句来执行此操作更安全吗?我是否应该为涉及使用mysql的所有内容使用预准备语句?为什么?
我真的很感激任何答案和反馈.谢谢.
Dar*_*ren 33
TL/DR
mysql_*函数已弃用.(注意大红色的盒子?)
警告此扩展在PHP 5.5.0中已弃用,并已在PHP 7.0.0中删除.相反,应该使用MySQLi或PDO_MySQL扩展.另请参阅MySQL:选择API指南和相关的常见问题解答以获取更多信息.该功能的替代方案包括:
你最好还是使用PDO或者MySQLi.2在使用预准备语句时,其中任何一个都可以作为兼容库.
信任用户输入而没有预先准备好的声明/消毒它就像把车停在一个不好的社区,解锁并点着钥匙.你基本上是在说,只是来吧,拿走我的好东西
你永远不应该,我的意思是永远不要相信用户输入.除非你想要这个:

参考数据并存储它,如评论中所述,您永远也不应该信任任何与用户相关的输入.除非您有101%确定用于操作所述数据库/值的数据是硬编码到您的应用程序中,否则您必须使用预准备语句.
现在说明为什么你应该使用预备语句.这很简单.要防止SQL注入,但要以最直接的方式实现.准备好的语句的工作方式很简单,它将查询和数据一起发送,但是分开(如果这样有意义哈哈) - 我的意思是:
Prepared Statements
Query: SELECT foo FROM bar WHERE foo = ?
Data: [? = 'a value here']
Run Code Online (Sandbox Code Playgroud)
与其前身相比,您使用数据截断查询,将其作为整体发送 - 反过来,这意味着它作为单个事务执行 - 导致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();
Run Code Online (Sandbox Code Playgroud)
更多阅读
TL;DR 如果您的应用接受任何用户输入,则 100% 的时间使用准备好的语句
你似乎有点困惑。首先,请不要使用mysql_*; 该mysql_*功能是过时的,过时和缺乏安全感。使用MySQLi或PDO代替。其次,mysql_num_rows与准备好的语句无关,无论如何都不是 PDO 功能。在运行查询之前准备语句,而不是在要计算行数时准备语句。
至于何时准备声明,@Mike'Pomax'Kamermans 在评论中明确指出。如果您曾经,甚至一次,使用任何曾经被用户接触过的数据——即使是被认为是受信任的用户——或者由任何类型的第三方或第三方应用程序(包括浏览器)生成,请使用准备好的语句。只有当您的数据 100% 是硬编码或完全由您的代码生成(如简单的计数器变量)时,您才能信任它。
例如,您不能信任:
当然,在将它们放入数据库之前,您应该验证所有这些(例如,检查电子邮件地址是否真的是电子邮件地址)。但即便如此,使用准备好的语句也是安全的方法。