更好的问题是你为什么不使用准备好的语句,给我一个很好的理由......
我想知道在 SQL 语句中使用 Session 变量是否安全。
没有。
用户是否可以修改会话变量?
不直接,但考虑一下
$_SESSION['value'] = $_POST['value'];
用户是否修改了会话?不,安全吗?没有。
所以你可能认为我永远不会这样做,但随着应用程序变得越来越复杂,你会知道你在会话中输入的每一个值都不会被用户数据触及。
考虑一下:
class foo{
function bar($value){
$db->query('select * from table where value ='.$value]);
}
}
$foo->bar($_SESSION['value']);
现在说一些其他文件做了我上面提到的(带有会话),你不能从糟糕的编写类的代码中看到这一点。您也无法通过查看课程来查看 Session 代码。因此,仅通过查看其中一个或另一个,您无法知道您正在做的事情是否安全。也许你在写的时候会保持警惕,那几个月、几年之后呢。你会记得吗?
准备好的语句之所以有效,是因为您可以在故障点看到这一点,因为它们不依赖其他地方的良好编码来弥补其糟糕的编码。
现在假设您想直接使用 Post 数组中的数据重用函数 bar,因为将其存储在会话中是一种浪费。所以你改变了它,但是不打开类你就无法知道它是否安全,这是另一个失败点的例子。
如果我们对这些使用准备好的语句会发生什么?我们会失去什么?几次击键。
没有人设法利用你的糟糕书面课程,我们会失去什么,这取决于你的网站做什么,你可能会失去很多。也许你没有有价值的数据,也许你有社会安全号码。谁知道呢,但不会好。至少你会失去用户对你的信任。
所以我再问一次,你为什么不对它们使用准备好的语句。
我的意思是最好的方式。这不值得。
顺便说一句
$db->prepare('SELECT Name FROM Users WHERE Years = :Years')
是一个准备好的语句,这是正确的方法。虽然这
$db->prepare("SELECT Name FROM Users WHERE Years = $Years")
不管你怎么做都不安全。
因此,如果您询问您在答案中使用的代码是否安全。那么是的,它看起来是这样的。但如果你问这是否安全:
$db->query("SELECT Name FROM Users WHERE Years = {$_SESSION['Years']}")
那我会说不,永远不会。
基本上你可以将任何你想要的东西放在一个准备好的语句中并让它安全,这就是它的全部意义所在。因为您在问,我很确定您还没有真正了解 SQLInjection 攻击的基础知识。因为 SQL Statement 和 Prepared Statement 之间有很大的区别。
网络上有很多关于此的视频教程,但这里作为先前的答案进行了一些解释。
How does SQL-injection work and how do I protect against it