我在应用程序中有以下代码(非常遗留):
results << User.all(
:select => "'#{entry.name}' AS user_name, '#{entry.lastname}, #{entry.firstname}' AS user_full_name, display_name",
:order => "display_name")
哪个生成以下查询我得到以下oci错误:
OCIError: ORA-01756: quoted string not properly terminated:
SELECT 'theupsstore2579' AS user_name, 'O'Brien, Perry' AS user_full_name, display_name FROM "Users" WHERE..
有没有一种方法可以修复我的查询?
使用quote_string是一个很好的方法吗
答案 0 :(得分:0)
是的,有一个好方法。你不应该在sql查询中使用插值字符串,例如"string bit #{interpolated_bit}"
- 这对安全性非常不利,并导致SQL注入攻击。
在这种情况下 - 因为其中一个名称包含一个'
字符(在姓氏O'Brien
中 - 并且一旦将该值插入到您的SQL字符串中,它就像对待它一样对待它'
字符并结束字符串 - 即使在'
之后还有更多字符(即Brien
位)
然后会导致数据库出现语法错误。
然而 - 以这种方式使用插值字符串也会让您对SQL注入开放 - 如果有人在'; DROP TABLE users;
(或等效的)中键入其姓氏字段会怎么样?你的代码很高兴将它放入SQL并运行它?使用插值字符串的方式是 NOT 安全。但是Rails提供了 安全的替代方案 - 而且它们是你应该经常使用的。
例如内置的arel方法(where
select
order
等)并使用已清理的?
语法,而不是
results << User.all(
:select => "'#{entry.name}' AS user_name, '#{entry.lastname}, #{entry.firstname}' AS user_full_name, display_name",
:order => "display_name")
你可以尝试
results << User.select("'?' AS user_name, '?, ?' AS user_full_name, display_name", entry.name, entry.lastname, entry.firstname).order("display_name")
(虽然我质疑你为什么要强迫所有用户使用相同的名字 - 你真的希望这些条件只选择那些名字的用户吗?)
我强烈建议您仔细阅读所有Rails指南。在这种情况下尤其是关于如何使用Active Record queries:
的那个您也可以阅读安全指南 - 特别是在这种情况下,Rails guide SQL injection section