参数化查询允许通过特殊参数而不是直接通过变量替换的方式将值传递到查询中。这增强了安全性,防止 SQL 注入,同时通过计划缓存加快了重复查询的执行。
动态 SQL 允许实时构建和执行查询(例如,使用 MS SQL 中的 EXEC sp_executesql 或 PostgreSQL 中的 PREPARE/EXECUTE)。必须非常小心:直接在查询文本中插入值可能导致 SQL 注入、语法错误和性能不佳。
参数化查询示例(使用 psycopg2 库的 Python):
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
PostgreSQL 中的动态 SQL 示例:
EXECUTE format('SELECT * FROM %I WHERE value = %L', tablename, value);
问题: 为什么简单地转义引号(')如某些旧应用程序所做的方式不足以防止 SQL 注入?
回答:
转义引号无法保护所有类型的注入,尤其是当攻击者插入 SQL 查询结构(例如,"; DROP TABLE users;")时。此外,它并不涵盖不同数据类型的所有特性,也无法防止通过编码或特殊字符绕过过滤器。始终应使用参数化查询。
故事
故事
故事
在 CRM 中,字母“O'Connor”在构建 SQL 查询时导致应用程序错误,因字符串简单拼接而未转义的单引号使得任何带有此姓氏的条目都无法保存,这一问题直到一年后才被发现。