我有一个(相对)简单的互动网站。我不在循环中运行查询。所有输入都是字符串,整数或图像。我确认所有整数和图像数据类型,并在所有字符串上使用mysqli_real_escape_string()。
除了传福音之外,我还可以通过参数化查询使用预准备语句获得哪些优势?
我发现的其他答案并未涉及此具体比较。
答案 0 :(得分:0)
我会尝试摘自Hitchhiker's Guide to SQL Injection prevention:
因为它是手动的。 手动意味着容易出错。这取决于程序员的技能,脾气,情绪,昨晚的啤酒数量等等。事实上,手动格式化是世界上大多数注射案例的唯一原因。为什么呢?
手动格式可能不完整。
我们来看看Bobby Tables的案例吧。这是不完整格式化的完美示例:我们添加到查询中的字符串被引用但未转义!虽然我们从上面得知,引用和转义应始终一起应用(同时为转义函数设置正确的编码)。但是在一个通常的PHP应用程序中,它单独执行SQL字符串格式化(部分在查询中,部分在其他地方),很可能很容易忽略格式化的某些部分。
手动格式可以应用于错误的文字 只要我们使用完整格式化(因为它会导致立即错误,可以在开发阶段修复),这不是什么大问题,但结合不完整的格式化,这是一场真正的灾难。在Stack Overflow这个伟大的网站上有数百个答案,建议以与字符串相同的方式转义标识符。这完全没用,直接注射。
手动格式化基本上是非强制性措施 首先,明显缺乏关注案例,可以简单地忘记正确的格式。但是有一个非常奇怪的情况 - 许多PHP用户经常故意拒绝应用任何格式,因为直到今天他们仍然将数据分离为“干净”和“不干净”,“用户输入”和“非用户输入“等。意味着”安全“数据不需要格式化。这是一个简单的废话 - 记得Sarah O'Hara。从格式化的角度来看,重要的是目的地。开发人员必须考虑类型的SQL文字,而不是数据源。这个字符串是否会进入查询?它必须格式化然后。无论如何,如果它来自用户输入或只是在代码执行中神秘地出现。
手动格式可以与实际查询执行分开相当长的距离。
最被低估和忽视的问题。然而,最重要的是,如果没有遵循的话,它可以破坏所有其他规则
几乎每个PHP用户都试图在一个地方进行所有“清理”,远离实际的查询执行,这种错误的方法是无数错误的来源:
毕竟,手动格式化将始终占用代码中的额外空间,使其纠结和膨胀。
正确实现的参数化查询可以使您的代码难以置信。用于演示的伪代码:
$data = DB::call("SELECT * FROM t WHERE foo=? AND bar=?", [$foo, $bar])->fetchAll();
此单行代码将为您提供数据库中的行数组。手动格式化需要多少行?