aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-03-18 06:47:40 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-03-18 06:52:41 +0900
commit2d5d537d19d62e9c132cf49f7dbc9eb8ff9190e3 (patch)
treec5aa4cb4e52fdc37ccb673f1349bb23787eb42ea /activerecord
parentc399f7d07a88d333fa05a361c66a252d9fa462bb (diff)
downloadrails-2d5d537d19d62e9c132cf49f7dbc9eb8ff9190e3.tar.gz
rails-2d5d537d19d62e9c132cf49f7dbc9eb8ff9190e3.tar.bz2
rails-2d5d537d19d62e9c132cf49f7dbc9eb8ff9190e3.zip
Add test case to prevent possible SQL injection
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/arel/visitors/to_sql.rb4
-rw-r--r--activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb10
3 files changed, 23 insertions, 1 deletions
diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb
index 7e3e265208..72efac72bf 100644
--- a/activerecord/lib/arel/visitors/to_sql.rb
+++ b/activerecord/lib/arel/visitors/to_sql.rb
@@ -805,7 +805,9 @@ module Arel # :nodoc: all
end
def sanitize_as_sql_comment(o)
- o.expr.map { |v| v.gsub(%r{ /\*\+?\s* | \s*\*/ }x, "") }
+ o.expr.map { |v|
+ v.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
+ }
end
def collect_optimizer_hints(o, collector)
diff --git a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
index 31a002e935..b9794c5710 100644
--- a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
@@ -13,13 +13,23 @@ if supports_optimizer_hints?
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
end
+ end
+ def test_optimizer_hints_is_sanitized
assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
end
+ assert_sql(%r{\ASELECT /\*\+ `posts`\.\*, \*/}) do
+ posts = Post.optimizer_hints("**// `posts`.*, //**")
+ posts = posts.select(:id).where(author_id: [0, 1])
+ assert_equal({ "id" => 1 }, posts.first.as_json)
+ end
+ end
+
+ def test_optimizer_hints_with_unscope
assert_sql(%r{\ASELECT `posts`\.`id`}) do
posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
posts = posts.select(:id).where(author_id: [0, 1])
diff --git a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
index 4fac7ffdc0..5e4bf232e1 100644
--- a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
@@ -17,13 +17,23 @@ if supports_optimizer_hints?
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "Seq Scan on posts"
end
+ end
+ def test_optimizer_hints_is_sanitized
assert_sql(%r{\ASELECT /\*\+ SeqScan\(posts\) \*/}) do
posts = Post.optimizer_hints("/*+ SeqScan(posts) */")
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "Seq Scan on posts"
end
+ assert_sql(%r{\ASELECT /\*\+ "posts"\.\*, \*/}) do
+ posts = Post.optimizer_hints("**// \"posts\".*, //**")
+ posts = posts.select(:id).where(author_id: [0, 1])
+ assert_equal({ "id" => 1 }, posts.first.as_json)
+ end
+ end
+
+ def test_optimizer_hints_with_unscope
assert_sql(%r{\ASELECT "posts"\."id"}) do
posts = Post.optimizer_hints("/*+ SeqScan(posts) */")
posts = posts.select(:id).where(author_id: [0, 1])