rails mysql正则表达式输入没有正确清理

时间:2017-01-09 10:50:13

标签: mysql ruby-on-rails ruby ruby-on-rails-3

我在rails 3应用程序上执行以下操作

def test(str)
    User.where("name REGEXP ?",str).last
end

使用上面的格式,rails通常会处理输入的清理。但是在少数情况下失败了。

如果我使用

str = "hi\\"

我收到此错误: -

ActiveRecord::StatementInvalid: Mysql2::Error: Got error 'trailing backslash (\)' from regexp: SELECT  `users`.* FROM `users`  WHERE (name REGEXP 'hi\\') ORDER BY `users`.`id` DESC LIMIT 1

如果我使用

str="hi("

我收到此错误

ActiveRecord::StatementInvalid: Mysql2::Error: Got error 'parentheses not balanced' from regexp: SELECT  `users`.* FROM `users`  WHERE (name REGEXP 'hi(') ORDER BY `users`.`id` DESC LIMIT 1

对于像str =“hi”这样的情况,它可以工作: -

在regex sql中执行输入之前是否有干净的rails处理输入?

1 个答案:

答案 0 :(得分:2)

安全变体

您可以使用Regexp.escape。但它可能会否定使用Regexp的目的:

对于MySQL:

def test(str)
  User.where("name REGEXP ?", Regexp.escape(str) ).last
end

对于Postgres:

def test(str)
  User.where("name ~ ?", Regexp.escape(str) ).last
end

在本地Postgres数据库上测试:

Movie.where("title ~ ?", '*')
#=> PG::InvalidRegularExpression: ERROR:  invalid regular expression: quantifier operand invalid

Movie.where("title ~ ?", Regexp.escape('*'))
#=> [Everything You Always Wanted to Know About Sex * But Were Afraid to Ask]

不安全的变种

确保您的输入正确无误。强大的力量带来了巨大的责任!

Movie.where("title ~ ?", 'a{2,}')
#=> [Mou gaan dou, Der Baader Meinhof Komplex, De helaasheid der dingen]

Movie.where("title ~ ?", "\\(").first
#=> (500) Days of Summer

Movie.where("title ~ ?", "[^0-9a-zA-Z \.\-]")

对于您的示例,您需要str="hi\\\\"str="hi\\("