具体来说,准备好的陈述在这种情况下有什么优势

时间:2016-04-15 18:15:24

标签: php mysqli sql-injection

我有一个(相对)简单的互动网站。我不在循环中运行查询。所有输入都是字符串,整数或图像。我确认所有整数和图像数据类型,并在所有字符串上使用mysqli_real_escape_string()。

除了传福音之外,我还可以通过参数化查询使用预准备语句获得哪些优势?

我发现的其他答案并未涉及此具体比较。

1 个答案:

答案 0 :(得分:0)

我会尝试摘自Hitchhiker's Guide to SQL Injection prevention

为什么手动格式化不好?

因为它是手动的。 手动意味着容易出错。这取决于程序员的技能,脾气,情绪,昨晚的啤酒数量等等。事实上,手动格式化是世界上大多数注射案例的唯一原因。为什么呢?

  1. 手动格式可能不完整。
    我们来看看Bobby Tables的案例吧。这是不完整格式化的完美示例:我们添加到查询中的字符串被引用但未转义!虽然我们从上面得知,引用和转义应始终一起应用(同时为转义函数设置正确的编码)。但是在一个通常的PHP应用程序中,它单独执行SQL字符串格式化(部分在查询中,部分在其他地方),很可能很容易忽略格式化的某些部分。

  2. 手动格式可以应用于错误的文字 只要我们使用完整格式化(因为它会导致立即错误,可以在开发阶段修复),这不是什么大问题,但结合不完整的格式化,这是一场真正的灾难。在Stack Overflow这个伟大的网站上有数百个答案,建议以与字符串相同的方式转义标识符。这完全没用,直接注射。

  3. 手动格式化基本上是非强制性措施 首先,明显缺乏关注案例,可以简单地忘记正确的格式。但是有一个非常奇怪的情况 - 许多PHP用户经常故意拒绝应用任何格式,因为直到今天他们仍然将数据分离为“干净”和“不干净”,“用户输入”和“非用户输入“等。意味着”安全“数据不需要格式化。这是一个简单的废话 - 记得Sarah O'Hara。从格式化的角度来看,重要的是目的地。开发人员必须考虑类型的SQL文字,而不是数据源。这个字符串是否会进入查询?它必须格式化然后。无论如何,如果它来自用户输入或只是在代码执行中神秘地出现。

  4. 手动格式可以与实际查询执行分开相当长的距离。
    最被低估和忽视的问题。然而,最重要的是,如果没有遵循的话,它可以破坏所有其他规则 几乎每个PHP用户都试图在一个地方进行所有“清理”,远离实际的查询执行,这种错误的方法是无数错误的来源:

    • 首先,由于手头没有查询,人们无法分辨出这段特定数据将代表什么样的SQL文字 - 因此同时违反了格式规则(1)和(2)。
    • 有一个以上的地方进行补充,我们要求发生灾难,因为一个开发人员会认为它是由另一个人完成的,或者已经在其他地方做过,等等。
    • 有多个地方用于纯化,我们引入了另一种危险,即双重清理数据(例如,一个开发人员在入口点格式化它,另一个在查询执行之前)
    • 过早格式化很可能会破坏源变量,使其无法在其他地方使用。
  5. 毕竟,手动格式化将始终占用代码中的额外空间,使其纠结和膨胀。

  6. 正确实现的参数化查询可以使您的代码难以置信。用于演示的伪代码:

    $data = DB::call("SELECT * FROM t WHERE foo=? AND bar=?", [$foo, $bar])->fetchAll();
    

    单行代码将为您提供数据库中的行数组。手动格式化需要多少行?