【发布时间】:2019-11-17 20:31:43
【问题描述】:
LIKE 具有用户提供输入的运算符
Postgres LIKE 运算符对于向用户提供对表行的基本搜索非常有用。但是,LIKE 运算符的用户提供的输入需要正确转义,因为正在解释某些字符,例如下划线 (_)。始终建议通过 Postgres prepared statment 传递用户提供的输入:
PREPARE getUsernames(text) AS
SELECT "name" FROM "users" WHERE "name" LIKE '%' || $1 || '%';
EXECUTE getUsernames('_')
虽然通过预准备语句中的变量传递用户输入,但下划线被 LIKE 运算符解释为通配符,因此上述 SQL 查询匹配用户表中的每个条目。
建议的解决方案
用户期望搜索下划线会返回所有name 包含下划线字符(而不是将其解释为通配符)的结果。因此,我们必须对用户输入进行转义,以使其永远不会被LIKE 运算符解释。 Postgres 提供了转义字符的规范,默认情况下是反斜杠。所以每个具有特殊含义的字符都必须使用这个转义字符进行转义。但是,保留字符黑名单容易出错,因为总是有可能拥有不完整的黑名单。
因此,我提出的解决方案的想法是始终在用户输入的每个字符前面加上转义字符,而不管它是否会被实际解释。 Postgres 接受这种不需要转义的字符的转义。
这是一个用 TypeScript 编写的用户输入转义的示例实现:
function escapePostgresLikeStr(str: string, escapeChar = '\\'): string {
return str
.split('')
.map(char => `${escapeChar}${char}`)
.join('');
}
我没有找到有关此特定问题的任何信息,因此欢迎提供任何反馈、安全考虑和改进! :)
干杯, derbenoo
【问题讨论】:
标签: sql postgresql user-input