每个人都知道或应该知道参数化查询有助于防止SQL注入。我见过的所有教程和文档都围绕着使用准备好的SQL查询来处理表单输入。但是什么时候没有任何表格输入呢?即用户登录后的后续查询,例如$stmt = "SELECT theme_preference FROM users WHERE user_id = '1234'";
$query = mysqli_query($conn, $stmt);
攻击者是否有可能利用此方法? (让我们说我使用PHP)。
答案 0 :(得分:5)
问题不在于在SQL查询中编写的数据源是否是http表单。它不是来自当前的请求。
问题是您是否信任数据来源。这可能是一个复杂的问题。
你显然不相信来自当前请求的东西。您也不相信可能来自早期请求的内容,例如数据库中由请求数据修改的示例字段。但您也可能信任或不信任数据库中的其他字段。例如,您有IT运营人员或数据库管理员。您是否相信他们不会将某种XSS或二级SQLi攻击注入数据库字段以窃取存储在审计表中的用户信用卡数据,这样他们就不能直接进入并转储而不会被注意到?如果他们在未经审核的表格中的正确位置注入了javascript或聪明的SQLi,他们可能会利用易受攻击的应用程序窃取信用卡信息,然后将其更改回去并删除所有痕迹。
此外,应用程序可能具有不同的数据源,其他系统可能例如在API上上传文件(比如XML),将处理来自这些文件的数据,其中一些最终会进入UI或在SQL查询中使用。如果您信任这些源,则可以选择不实施针对SQLi或XSS的保护。但是,为什么你这么容易?多层防御总是比在冰上行走更好。
简而言之,问题就是信任。如果您完全信任数据源(例如,因为它是静态的,硬编码的或其他原因),那么直接在查询中使用它是可以的。但是在SQL注入的情况下,正确使用它(即在参数中)是如此简单,你应该这样做。
还要考虑未来的变化。您在没有参数的SQL字符串中编写它,因为您知道它现在是安全的。几个月过去了,有人添加了一个新功能,修改了你的查询,添加了一些参数,一个来自请求。但是模式已经存在,他可能只是复制粘贴并使用模式 - 并且您的应用程序容易受到攻击。
我的最后一点是静态安全扫描程序,即那些查看源代码的程序。如果变量包含在查询字符串本身而不使用参数,那么几乎所有这些都会标记SQLi的代码。这当然可能是假阳性,但我怀疑你是否想要对这些发现感到困扰,当你可以首先避免它们时。
因此,有时它不仅仅是技术可利用性,还有其他方面。