具有用户提供输入的LIKE
运算符
Postgres 喜欢操作符对于向用户提供表行的基本搜索非常有用。但是,用户为LIKE
操作符提供的输入需要正确转义,因为某些字符(如下划线(_
)正在被解释)。始终建议通过Postgres 准备状态传递用户提供的输入。
PREPARE getUsernames(text) AS
SELECT "name" FROM "users" WHERE "name" LIKE '%' || $1 || '%';
EXECUTE getUsernames('_')
虽然通过准备语句中的变量传递用户输入,但LIKE
操作符将下划线解释为通配符,以便上面的SQL查询与user表中的每个条目匹配。
拟议解决方案
用户期望搜索下划线返回name
包含下划线字符的所有结果(而不是解释为通配符)。因此,我们必须转义用户输入,使其永远不会被LIKE
操作符解释。Postgres提供了转义字符的规范,默认情况下它是反斜杠。因此,每个具有特殊意义的字符都必须使用这个转义字符进行转义。然而,保持一个黑名单的字符感觉容易出错,因为总有可能有一个不完整的黑名单。因此,我所建议的解决方案的思想是,总是在用户输入的每个字符前面加上转义字符,而不管它是否会被实际解释。Postgres接受对不需要转义的字符进行转义。
下面是用TypeScript编写的用户输入转义的一个示例实现:
function escapePostgresLikeStr(str: string, escapeChar = '\\'): string {
return str
.split('')
.map(char => `${escapeChar}${char}`)
.join('');
}
我没有发现有关这个问题的任何信息,因此欢迎任何反馈、安全考虑和改进!)
干杯,德贝诺
发布于 2019-11-16 22:10:57
如果不希望使用通配符,就不要使用like
。相反:
where position(? in name) > 0
请注意,?
是一个参数占位符,因此您不必使用(危险的)用户输入来处理查询字符串。
如果希望用户利用通配符,可以使用LIKE
(或者更好的正则表达式)。否则,我看不出这有什么好处。
https://stackoverflow.com/questions/58895632
复制相似问题