We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
2 parents 0443620 + dbd33d1 commit 9c51514Copy full SHA for 9c51514
4 files changed
ruby/ql/lib/change-notes/2024-03-08-activerecord-from.md
@@ -0,0 +1,4 @@
1
+---
2
+category: minorAnalysis
3
4
+* The second argument, `subquery_name`, of the `ActiveRecord::QueryMethods::from` method, is now recognized as an sql injection sink.
ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll
@@ -175,14 +175,14 @@ private predicate sqlFragmentArgumentInner(DataFlow::CallNode call, DataFlow::No
175
call =
176
activeRecordQueryBuilderCall([
177
"delete_all", "delete_by", "destroy_all", "destroy_by", "exists?", "find_by", "find_by!",
178
- "find_or_create_by", "find_or_create_by!", "find_or_initialize_by", "find_by_sql", "from",
179
- "having", "lock", "not", "where", "rewhere"
+ "find_or_create_by", "find_or_create_by!", "find_or_initialize_by", "find_by_sql", "having",
+ "lock", "not", "where", "rewhere"
180
]) and
181
sink = call.getArgument(0)
182
or
183
184
185
- "group", "joins", "order", "reorder", "pluck", "select", "reselect"
+ "from", "group", "joins", "order", "reorder", "pluck", "select", "reselect"
186
187
sink = call.getArgument(_)
188
ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb
@@ -114,6 +114,12 @@ def some_request_handler
114
User.joins(:a, params[:column])
115
116
User.count_by_sql(params[:custom_sql_query])
117
+
118
+ # BAD: executes `SELECT users.* FROM #{params[:tab]}`
119
+ # where `params[:tab]` is unsanitized
120
+ User.all.from(params[:tab])
121
+ # BAD: executes `SELECT "users".* FROM (SELECT "users".* FROM "users") #{params[:sq]}
122
+ User.all.from(User.all, params[:sq])
123
end
124
125
0 commit comments