我正在更新一些无法正确处理用户输入的遗留代码。该代码确实进行了最小程度的清理,但未涵盖所有已知威胁。
我们的新代码使用参数化查询。据我了解,查询是预编译的,输入被简单地视为无法执行的数据。在这种情况下,没有必要进行消毒。是吗?
换句话说,如果我在这个遗留代码中参数化查询,是否可以消除它目前的清理工作?或者我在参数化之上缺少一些额外的消毒效果?
答案 0 :(得分:5)
参数化查询将有助于防止SQL注入,但它们不会对跨站点脚本执行起作用。您需要其他措施,如HTML编码或HTML检测/验证,以防止这种情况。如果你关心的只是SQL注入,那么参数化查询就足够了。
答案 1 :(得分:5)
SQL查询参数确实可以很好地防御SQL注入。嵌入式引号或其他特殊字符不能造成恶作剧。
但是SQL查询的某些组件无法参数化。例如。表名,列名,SQL关键字。
$sql = "SELECT * FROM MyTable ORDER BY {$columnname} {$ASC_or_DESC}";
因此,在插入SQL查询之前,您可能需要验证动态内容的一些示例。白名单值也是一种很好的技术。
此外,您可以拥有列数据类型允许的值,但这些值是无意义的。对于这些情况,使用应用程序代码进行验证通常比尝试在SQL约束中验证更容易。
假设您存储了信用卡号。信用卡号码有效模式,图书馆可以识别无效模式中的有效模式。
或者用户何时定义密码?您可能希望确保足够的密码强度,或验证用户在两个密码输入字段中输入相同的字符串。
或者,如果他们订购了一定数量的商品,您可能需要将数量存储为整数但是您要确保它大于零,如果它大于1000,您可能需要加倍 - 检查用户输入的是否正确。
答案 2 :(得分:2)
清理和验证有许多不同的原因,包括阻止跨站点脚本编写,以及只是想要一个字段的正确内容(电话号码中没有名称)。参数化查询消除了手动清理或逃避SQL注入的需要。
请参阅my previous answers之一。
答案 3 :(得分:1)
你是对的,SQL参数不是可执行代码,所以你不必担心。
但是,您仍应进行一些验证。例如,如果您期望varchar(10)并且用户输入的内容长于此值,则最终会出现异常。
答案 4 :(得分:1)
总之没有。输入清理和参数化查询的使用不是互斥的,它们是独立的:既不能单独使用,也不能单独使用,或两者都使用。它们可以防止不同类型的攻击。使用两者是最好的课程。
答案 5 :(得分:1)
重要的是要注意,作为一个小问题,有时编写包含动态SQL的存储过程很有用。在这种情况下,输入参数化的事实不是针对SQL注入的自动防御。这似乎是一个相当明显的观点,但我常常遇到那些认为因为他们的输入被参数化而他们可以不再担心SQL注入的人。