我想找到行,其中文本列与用户给定的字符串,如开始SELECT * FROM users WHERE name LIKE 'rob%'
,而是“抢”是未经验证的用户输入。 如果用户编写包含像“rob_”的特殊模式字符的字符串,它会同时匹配“robert42”和“rob_the_man”。 我需要确保该字符串字面匹配,我该怎么做? 我需要处理上的应用程序级别的转义或者是一个更华丽的方式?
我使用PostgreSQL 9.1和去-pgsql的对围棋。
我想找到行,其中文本列与用户给定的字符串,如开始SELECT * FROM users WHERE name LIKE 'rob%'
,而是“抢”是未经验证的用户输入。 如果用户编写包含像“rob_”的特殊模式字符的字符串,它会同时匹配“robert42”和“rob_the_man”。 我需要确保该字符串字面匹配,我该怎么做? 我需要处理上的应用程序级别的转义或者是一个更华丽的方式?
我使用PostgreSQL 9.1和去-pgsql的对围棋。
该_和%字符必须被引用,可以在LIKE语句字面匹配,有没有办法解决它。 选择是有关客户端或服务器端(通常是使用SQL取代(),见下文)这样做。 也让它在一般情况下,100%正确的,都需要考虑几件事情。
默认情况下,引号字符之前使用_或%是反斜线(\),但它可以用ESCAPE子句立即LIKE子句以下改变。 在任何情况下,引用字符具有在图案被重复两次,以被作为一个字符字面上匹配。
例如: ... WHERE field like 'john^%node1^^node2.uucp@%' ESCAPE '^'
将匹配约翰节点1%^ @ node2.uccp其次是什么。
有使用默认选项反斜杠的问题:它已经用于其他目的时standard_conforming_strings为OFF(PG 9.1有它在缺省情况下,但以前的版本是仍被广泛使用,这是考虑点)。
此外,如果引用的LIKE通配符在用户输入注入方案在客户端完成,谈到除了正常的字符串报价已经需要用户输入。
在去-pgsql的例子一瞥告诉它使用$变量的N-风格占位符......因此,这里是把它写在某种程度上通用的方法,企图:它standard_conforming_strings是双向开启或关闭,使用服务器端的更换[%_],另一种引号字符,引述引号字符的,并且避免了SQL注入:
db.Query("SELECT * from USERS where name like replace(replace(replace($1,'^','^^'),'%','^%'),'_','^_') ||'%' ESCAPE '^'",
variable_user_input);
逃脱下划线和百分比把在图案中使用like
表达式使用转义字符:
SELECT * FROM users WHERE name LIKE replace(replace(user_input, '_', '\\_'), '%', '\\%');
至于我可以告诉唯一的特殊字符与LIKE操作员%,而强调,这些可以很容易地使用反斜杠手动逃脱。 这不是很漂亮,但它的工作原理。
SELECT * FROM users WHERE name LIKE
regexp_replace('rob', '(%|_)', '\\\1', 'g') || '%';
我觉得奇怪的是有附带的PostgreSQL没有这样的功能。 谁希望自己的用户编写他们自己的模式?
最好的答案是,你不应该插用户输入到SQL可言。 甚至逃避SQL仍然是危险的。
它采用去的DB / SQL库下面举例说明一个更安全的方式。 替换的准备和Exec用无论你去PostgreSQL库的等价物要求。
// The question mark tells the database server that we will provide
// the LIKE parameter later in the Exec call
sql := "SELECT * FROM users where name LIKE ?"
// no need to escape since this won't be interpolated into the sql string.
value := "%" + user_input
// prepare the completely safe sql string.
stmt, err := db.Prepare(sql)
// Now execute that sql with the values for every occurence of the question mark.
result, err := stmt.Exec(value)
这样做的好处是,用户输入可以安全而不用担心它的SQL注入到您运行这些语句的使用。 您还可以重复使用的多个查询,可以在某些情况下更有效地准备的SQL的好处。