Merge pull request #224 from github/sqli-override-fp

rb/sql-injection: fix FPs stemming from not accounting for overridden methods
This commit is contained in:
Alex Ford
2021-06-30 17:20:14 +01:00
committed by GitHub
6 changed files with 198 additions and 94 deletions

View File

@@ -44,19 +44,22 @@ class ActiveRecordModelClass extends ClassDeclaration {
/** A class method call whose receiver is an `ActiveRecordModelClass`. */
class ActiveRecordModelClassMethodCall extends MethodCall {
private ActiveRecordModelClass recvCls;
ActiveRecordModelClassMethodCall() {
// e.g. Foo.where(...)
exists(ActiveRecordModelClass recvCls |
recvCls.getModule() = resolveScopeExpr(this.getReceiver())
)
recvCls.getModule() = resolveScopeExpr(this.getReceiver())
or
// e.g. Foo.joins(:bars).where(...)
this.getReceiver() instanceof ActiveRecordModelClassMethodCall
recvCls = this.getReceiver().(ActiveRecordModelClassMethodCall).getReceiverClass()
or
// e.g. self.where(...) within an ActiveRecordModelClass
this.getReceiver() instanceof Self and
this.getEnclosingModule() instanceof ActiveRecordModelClass
this.getEnclosingModule() = recvCls
}
/** The `ActiveRecordModelClass` of the receiver of this method. */
ActiveRecordModelClass getReceiverClass() { result = recvCls }
}
private Expr sqlFragmentArgument(MethodCall call) {
@@ -116,8 +119,6 @@ class PotentiallyUnsafeSqlExecutingMethodCall extends ActiveRecordModelClassMeth
private Expr sqlFragmentExpr;
// TODO: `find` with `lock:` option also takes an SQL fragment
// TODO: refine this further to account for cases where the method called has
// been overriden to perform validation on its arguments
PotentiallyUnsafeSqlExecutingMethodCall() {
exists(Expr arg |
arg = sqlFragmentArgument(this) and
@@ -126,6 +127,11 @@ class PotentiallyUnsafeSqlExecutingMethodCall extends ActiveRecordModelClassMeth
sqlFragmentExpr = arg
or
sqlFragmentExpr = arg.(ArrayLiteral).getElement(0)
) and
// Check that method has not been overridden
not exists(SingletonMethod m |
m.getName() = this.getMethodName() and
m.getOuterScope() = this.getReceiverClass()
)
)
}

View File

@@ -1,18 +1,32 @@
actionControllerControllerClasses
| ActiveRecordInjection.rb:12:1:34:3 | FooController |
| ActiveRecordInjection.rb:37:1:48:3 | BarController |
| ActiveRecordInjection.rb:50:1:51:3 | BazController |
| ActiveRecordInjection.rb:27:1:58:3 | FooController |
| ActiveRecordInjection.rb:60:1:90:3 | BarController |
| ActiveRecordInjection.rb:92:1:96:3 | BazController |
actionControllerParamsCalls
| ActiveRecordInjection.rb:19:30:19:35 | call to params |
| ActiveRecordInjection.rb:22:29:22:34 | call to params |
| ActiveRecordInjection.rb:25:31:25:36 | call to params |
| ActiveRecordInjection.rb:29:20:29:25 | call to params |
| ActiveRecordInjection.rb:32:48:32:53 | call to params |
| ActiveRecordInjection.rb:40:10:40:15 | call to params |
| ActiveRecordInjection.rb:35:30:35:35 | call to params |
| ActiveRecordInjection.rb:39:30:39:35 | call to params |
| ActiveRecordInjection.rb:43:32:43:37 | call to params |
| ActiveRecordInjection.rb:48:21:48:26 | call to params |
| ActiveRecordInjection.rb:54:34:54:39 | call to params |
| ActiveRecordInjection.rb:56:23:56:28 | call to params |
| ActiveRecordInjection.rb:56:38:56:43 | call to params |
| ActiveRecordInjection.rb:62:10:62:15 | call to params |
| ActiveRecordInjection.rb:72:11:72:16 | call to params |
| ActiveRecordInjection.rb:77:12:77:17 | call to params |
| ActiveRecordInjection.rb:83:12:83:17 | call to params |
| ActiveRecordInjection.rb:88:15:88:20 | call to params |
| ActiveRecordInjection.rb:94:22:94:27 | call to params |
actionControllerParamsSources
| ActiveRecordInjection.rb:19:30:19:35 | call to params |
| ActiveRecordInjection.rb:22:29:22:34 | call to params |
| ActiveRecordInjection.rb:25:31:25:36 | call to params |
| ActiveRecordInjection.rb:29:20:29:25 | call to params |
| ActiveRecordInjection.rb:32:48:32:53 | call to params |
| ActiveRecordInjection.rb:40:10:40:15 | call to params |
| ActiveRecordInjection.rb:35:30:35:35 | call to params |
| ActiveRecordInjection.rb:39:30:39:35 | call to params |
| ActiveRecordInjection.rb:43:32:43:37 | call to params |
| ActiveRecordInjection.rb:48:21:48:26 | call to params |
| ActiveRecordInjection.rb:54:34:54:39 | call to params |
| ActiveRecordInjection.rb:56:23:56:28 | call to params |
| ActiveRecordInjection.rb:56:38:56:43 | call to params |
| ActiveRecordInjection.rb:62:10:62:15 | call to params |
| ActiveRecordInjection.rb:72:11:72:16 | call to params |
| ActiveRecordInjection.rb:77:12:77:17 | call to params |
| ActiveRecordInjection.rb:83:12:83:17 | call to params |
| ActiveRecordInjection.rb:88:15:88:20 | call to params |
| ActiveRecordInjection.rb:94:22:94:27 | call to params |

View File

@@ -1,28 +1,46 @@
activeRecordModelClasses
| ActiveRecordInjection.rb:1:1:3:3 | UserGroup |
| ActiveRecordInjection.rb:5:1:7:3 | User |
| ActiveRecordInjection.rb:9:1:10:3 | Admin |
| ActiveRecordInjection.rb:5:1:17:3 | User |
| ActiveRecordInjection.rb:19:1:25:3 | Admin |
activeRecordSqlExecutionRanges
| ActiveRecordInjection.rb:19:30:19:44 | ...[...] |
| ActiveRecordInjection.rb:22:21:22:41 | "id = #{...}" |
| ActiveRecordInjection.rb:25:23:25:43 | "id = #{...}" |
| ActiveRecordInjection.rb:28:16:28:21 | <<-SQL |
| ActiveRecordInjection.rb:32:35:32:60 | "user.id = #{...}" |
| ActiveRecordInjection.rb:45:21:45:33 | ... + ... |
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" |
| ActiveRecordInjection.rb:23:17:23:25 | condition |
| ActiveRecordInjection.rb:35:30:35:44 | ...[...] |
| ActiveRecordInjection.rb:39:21:39:43 | "id = '#{...}'" |
| ActiveRecordInjection.rb:43:23:43:45 | "id = '#{...}'" |
| ActiveRecordInjection.rb:47:16:47:21 | <<-SQL |
| ActiveRecordInjection.rb:54:20:54:47 | "user.id = '#{...}'" |
| ActiveRecordInjection.rb:68:21:68:33 | ... + ... |
| ActiveRecordInjection.rb:75:16:75:28 | "name #{...}" |
| ActiveRecordInjection.rb:80:20:80:39 | "username = #{...}" |
activeRecordModelClassMethodCalls
| ActiveRecordInjection.rb:2:3:2:17 | call to has_many |
| ActiveRecordInjection.rb:6:3:6:24 | call to belongs_to |
| ActiveRecordInjection.rb:19:5:19:45 | call to calculate |
| ActiveRecordInjection.rb:22:5:22:42 | call to delete_all |
| ActiveRecordInjection.rb:25:5:25:45 | call to destroy_all |
| ActiveRecordInjection.rb:28:5:28:35 | call to where |
| ActiveRecordInjection.rb:32:5:32:27 | call to joins |
| ActiveRecordInjection.rb:32:5:32:61 | call to where |
| ActiveRecordInjection.rb:45:5:45:34 | call to delete_all |
| ActiveRecordInjection.rb:10:5:10:68 | call to find |
| ActiveRecordInjection.rb:15:5:15:40 | call to find_by |
| ActiveRecordInjection.rb:15:5:15:46 | call to users |
| ActiveRecordInjection.rb:23:5:23:26 | call to destroy_all |
| ActiveRecordInjection.rb:35:5:35:45 | call to calculate |
| ActiveRecordInjection.rb:39:5:39:44 | call to delete_all |
| ActiveRecordInjection.rb:43:5:43:47 | call to destroy_all |
| ActiveRecordInjection.rb:47:5:47:35 | call to where |
| ActiveRecordInjection.rb:54:5:54:14 | call to where |
| ActiveRecordInjection.rb:54:5:54:48 | call to not |
| ActiveRecordInjection.rb:56:5:56:51 | call to authenticate |
| ActiveRecordInjection.rb:68:5:68:34 | call to delete_all |
| ActiveRecordInjection.rb:75:5:75:29 | call to order |
| ActiveRecordInjection.rb:80:7:80:40 | call to find_by |
| ActiveRecordInjection.rb:85:5:85:33 | call to find_by |
| ActiveRecordInjection.rb:88:5:88:34 | call to find |
| ActiveRecordInjection.rb:94:5:94:46 | call to delete_all |
potentiallyUnsafeSqlExecutingMethodCall
| ActiveRecordInjection.rb:19:5:19:45 | call to calculate |
| ActiveRecordInjection.rb:22:5:22:42 | call to delete_all |
| ActiveRecordInjection.rb:25:5:25:45 | call to destroy_all |
| ActiveRecordInjection.rb:28:5:28:35 | call to where |
| ActiveRecordInjection.rb:32:5:32:61 | call to where |
| ActiveRecordInjection.rb:45:5:45:34 | call to delete_all |
| ActiveRecordInjection.rb:10:5:10:68 | call to find |
| ActiveRecordInjection.rb:23:5:23:26 | call to destroy_all |
| ActiveRecordInjection.rb:35:5:35:45 | call to calculate |
| ActiveRecordInjection.rb:39:5:39:44 | call to delete_all |
| ActiveRecordInjection.rb:43:5:43:47 | call to destroy_all |
| ActiveRecordInjection.rb:47:5:47:35 | call to where |
| ActiveRecordInjection.rb:54:5:54:48 | call to not |
| ActiveRecordInjection.rb:68:5:68:34 | call to delete_all |
| ActiveRecordInjection.rb:75:5:75:29 | call to order |
| ActiveRecordInjection.rb:80:7:80:40 | call to find_by |

View File

@@ -4,9 +4,24 @@ end
class User < ApplicationRecord
belongs_to :user_group
def self.authenticate(name, pass)
# BAD: possible untrusted input interpolated into SQL fragment
find(:first, :conditions => "name='#{name}' and pass='#{pass}'")
end
def self.from(user_group_id)
# GOOD: `find_by` with hash argument
UserGroup.find_by(id: user_group_id).users
end
end
class Admin < User
def self.delete_all(condition = nil)
# BAD: `delete_all` overrides an ActiveRecord method, but doesn't perform
# any validation before passing its arguments on to another ActiveRecord method
destroy_all(condition)
end
end
class FooController < ActionController::Base
@@ -15,37 +30,67 @@ class FooController < ActionController::Base
# A string tainted by user input is inserted into an SQL query
def some_request_handler
# SELECT AVG(#{params[:column]}) FROM "users"
# BAD: executes `SELECT AVG(#{params[:column]}) FROM "users"`
# where `params[:column]` is unsanitized
User.calculate(:average, params[:column])
# DELETE FROM "users" WHERE (id = #{params[:id]})
User.delete_all("id = #{params[:id]}")
# BAD: executes `DELETE FROM "users" WHERE (id = '#{params[:id]}')`
# where `params[:id]` is unsanitized
User.delete_all("id = '#{params[:id]}'")
# SELECT "users".* FROM "users" WHERE (id = #{params[:id]})
User.destroy_all(["id = #{params[:id]}"])
# BAD: executes `SELECT "users".* FROM "users" WHERE (id = '#{params[:id]}')`
# where `params[:id]` is unsanitized
User.destroy_all(["id = '#{params[:id]}'"])
# SELECT "users".* FROM "users" WHERE id BETWEEN #{params[:min_id]} AND 100000
# BAD: executes `SELECT "users".* FROM "users" WHERE id BETWEEN '#{params[:min_id]}' AND 100000`
# where `params[:min_id]` is unsanitized
User.where(<<-SQL, MAX_USER_ID)
id BETWEEN #{params[:min_id]} AND ?
id BETWEEN '#{params[:min_id]}' AND ?
SQL
UserGroup.joins(:users).where("user.id = #{params[:id]}")
# BAD: chained method case
# executes `SELECT "users".* FROM "users" WHERE (NOT (user_id = 'params[:id]'))`
# where `params[:id]` is unsanitized
User.where.not("user.id = '#{params[:id]}'")
User.authenticate(params[:name], params[:pass])
end
end
class BarController < ApplicationController
def some_other_request_handler
ps = params
uid = ps[:id]
uidEq = "= '#{uid}'"
# DELETE FROM "users" WHERE (id = #{uid})
User.delete_all("id = " + uid)
# BAD: executes `DELETE FROM "users" WHERE (id = #{uid})`
# where `uid` is unsantized
User.delete_all("id " + uidEq)
end
def safe_paths
dir = params[:order]
# GOOD: barrier guard prevents taint flow
dir = "DESC" unless dir == "ASC"
User.order("name #{dir}")
name = params[:user_name]
# GOOD: barrier guard prevents taint flow
if %w(alice bob charlie).include? name
User.find_by("username = #{name}")
end
name = params[:user_name]
# GOOD: hash arguments are sanitized by ActiveRecord
User.find_by(user_name: name)
# OK: `find` method is overridden in `User`
User.find(params[:user_group])
end
end
class BazController < BarController
def yet_another_handler
Admin.delete_all(params[:admin_condition])
end
end

View File

@@ -9,9 +9,19 @@ class User < ApplicationRecord
# BAD: possible untrusted input interpolated into SQL fragment
find(:first, :conditions => "name='#{name}' and pass='#{pass}'")
end
def self.from(user_group_id)
# GOOD: `find_by` with hash argument
UserGroup.find_by(id: user_group_id).users
end
end
class Admin < User
def self.delete_all(condition = nil)
# BAD: `delete_all` overrides an ActiveRecord method, but doesn't perform
# any validation before passing its arguments on to another ActiveRecord method
destroy_all(condition)
end
end
class FooController < ActionController::Base
@@ -47,9 +57,7 @@ class FooController < ActionController::Base
end
end
class BarController < ApplicationController
def some_other_request_handler
ps = params
uid = ps[:id]
@@ -60,8 +68,7 @@ class BarController < ApplicationController
User.delete_all("id " + uidEq)
end
def sanitized_paths
def safe_paths
dir = params[:order]
# GOOD: barrier guard prevents taint flow
dir = "DESC" unless dir == "ASC"
@@ -76,8 +83,14 @@ class BarController < ApplicationController
name = params[:user_name]
# GOOD: hash arguments are sanitized by ActiveRecord
User.find_by(user_name: name)
# OK: `find` method is overridden in `User`
User.find(params[:user_group])
end
end
class BazController < BarController
def yet_another_handler
Admin.delete_all(params[:admin_condition])
end
end

View File

@@ -1,42 +1,50 @@
edges
| ActiveRecordInjection.rb:8:25:8:28 | name : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" |
| ActiveRecordInjection.rb:8:31:8:34 | pass : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" |
| ActiveRecordInjection.rb:25:30:25:35 | call to params : | ActiveRecordInjection.rb:25:30:25:44 | ...[...] |
| ActiveRecordInjection.rb:29:30:29:35 | call to params : | ActiveRecordInjection.rb:29:21:29:43 | "id = '#{...}'" |
| ActiveRecordInjection.rb:33:32:33:37 | call to params : | ActiveRecordInjection.rb:33:23:33:45 | "id = '#{...}'" |
| ActiveRecordInjection.rb:38:21:38:26 | call to params : | ActiveRecordInjection.rb:37:16:37:21 | <<-SQL |
| ActiveRecordInjection.rb:44:34:44:39 | call to params : | ActiveRecordInjection.rb:44:20:44:47 | "user.id = '#{...}'" |
| ActiveRecordInjection.rb:46:23:46:28 | call to params : | ActiveRecordInjection.rb:46:23:46:35 | ...[...] : |
| ActiveRecordInjection.rb:46:23:46:35 | ...[...] : | ActiveRecordInjection.rb:8:25:8:28 | name : |
| ActiveRecordInjection.rb:46:38:46:43 | call to params : | ActiveRecordInjection.rb:46:38:46:50 | ...[...] : |
| ActiveRecordInjection.rb:46:38:46:50 | ...[...] : | ActiveRecordInjection.rb:8:31:8:34 | pass : |
| ActiveRecordInjection.rb:54:10:54:15 | call to params : | ActiveRecordInjection.rb:60:21:60:33 | ... + ... |
| ActiveRecordInjection.rb:20:23:20:31 | condition : | ActiveRecordInjection.rb:23:17:23:25 | condition |
| ActiveRecordInjection.rb:35:30:35:35 | call to params : | ActiveRecordInjection.rb:35:30:35:44 | ...[...] |
| ActiveRecordInjection.rb:39:30:39:35 | call to params : | ActiveRecordInjection.rb:39:21:39:43 | "id = '#{...}'" |
| ActiveRecordInjection.rb:43:32:43:37 | call to params : | ActiveRecordInjection.rb:43:23:43:45 | "id = '#{...}'" |
| ActiveRecordInjection.rb:48:21:48:26 | call to params : | ActiveRecordInjection.rb:47:16:47:21 | <<-SQL |
| ActiveRecordInjection.rb:54:34:54:39 | call to params : | ActiveRecordInjection.rb:54:20:54:47 | "user.id = '#{...}'" |
| ActiveRecordInjection.rb:56:23:56:28 | call to params : | ActiveRecordInjection.rb:56:23:56:35 | ...[...] : |
| ActiveRecordInjection.rb:56:23:56:35 | ...[...] : | ActiveRecordInjection.rb:8:25:8:28 | name : |
| ActiveRecordInjection.rb:56:38:56:43 | call to params : | ActiveRecordInjection.rb:56:38:56:50 | ...[...] : |
| ActiveRecordInjection.rb:56:38:56:50 | ...[...] : | ActiveRecordInjection.rb:8:31:8:34 | pass : |
| ActiveRecordInjection.rb:62:10:62:15 | call to params : | ActiveRecordInjection.rb:68:21:68:33 | ... + ... |
| ActiveRecordInjection.rb:94:22:94:27 | call to params : | ActiveRecordInjection.rb:94:22:94:45 | ...[...] : |
| ActiveRecordInjection.rb:94:22:94:45 | ...[...] : | ActiveRecordInjection.rb:20:23:20:31 | condition : |
nodes
| ActiveRecordInjection.rb:8:25:8:28 | name : | semmle.label | name : |
| ActiveRecordInjection.rb:8:31:8:34 | pass : | semmle.label | pass : |
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | semmle.label | "name='#{...}' and pass='#{...}'" |
| ActiveRecordInjection.rb:25:30:25:35 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:25:30:25:44 | ...[...] | semmle.label | ...[...] |
| ActiveRecordInjection.rb:29:21:29:43 | "id = '#{...}'" | semmle.label | "id = '#{...}'" |
| ActiveRecordInjection.rb:29:30:29:35 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:33:23:33:45 | "id = '#{...}'" | semmle.label | "id = '#{...}'" |
| ActiveRecordInjection.rb:33:32:33:37 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:37:16:37:21 | <<-SQL | semmle.label | <<-SQL |
| ActiveRecordInjection.rb:38:21:38:26 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:44:20:44:47 | "user.id = '#{...}'" | semmle.label | "user.id = '#{...}'" |
| ActiveRecordInjection.rb:44:34:44:39 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:46:23:46:28 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:46:23:46:35 | ...[...] : | semmle.label | ...[...] : |
| ActiveRecordInjection.rb:46:38:46:43 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:46:38:46:50 | ...[...] : | semmle.label | ...[...] : |
| ActiveRecordInjection.rb:54:10:54:15 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:60:21:60:33 | ... + ... | semmle.label | ... + ... |
| ActiveRecordInjection.rb:20:23:20:31 | condition : | semmle.label | condition : |
| ActiveRecordInjection.rb:23:17:23:25 | condition | semmle.label | condition |
| ActiveRecordInjection.rb:35:30:35:35 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:35:30:35:44 | ...[...] | semmle.label | ...[...] |
| ActiveRecordInjection.rb:39:21:39:43 | "id = '#{...}'" | semmle.label | "id = '#{...}'" |
| ActiveRecordInjection.rb:39:30:39:35 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:43:23:43:45 | "id = '#{...}'" | semmle.label | "id = '#{...}'" |
| ActiveRecordInjection.rb:43:32:43:37 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:47:16:47:21 | <<-SQL | semmle.label | <<-SQL |
| ActiveRecordInjection.rb:48:21:48:26 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:54:20:54:47 | "user.id = '#{...}'" | semmle.label | "user.id = '#{...}'" |
| ActiveRecordInjection.rb:54:34:54:39 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:56:23:56:28 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:56:23:56:35 | ...[...] : | semmle.label | ...[...] : |
| ActiveRecordInjection.rb:56:38:56:43 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:56:38:56:50 | ...[...] : | semmle.label | ...[...] : |
| ActiveRecordInjection.rb:62:10:62:15 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:68:21:68:33 | ... + ... | semmle.label | ... + ... |
| ActiveRecordInjection.rb:94:22:94:27 | call to params : | semmle.label | call to params : |
| ActiveRecordInjection.rb:94:22:94:45 | ...[...] : | semmle.label | ...[...] : |
#select
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:46:23:46:28 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:46:23:46:28 | call to params | a user-provided value |
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:46:38:46:43 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:46:38:46:43 | call to params | a user-provided value |
| ActiveRecordInjection.rb:25:30:25:44 | ...[...] | ActiveRecordInjection.rb:25:30:25:35 | call to params : | ActiveRecordInjection.rb:25:30:25:44 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:25:30:25:35 | call to params | a user-provided value |
| ActiveRecordInjection.rb:29:21:29:43 | "id = '#{...}'" | ActiveRecordInjection.rb:29:30:29:35 | call to params : | ActiveRecordInjection.rb:29:21:29:43 | "id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:29:30:29:35 | call to params | a user-provided value |
| ActiveRecordInjection.rb:33:23:33:45 | "id = '#{...}'" | ActiveRecordInjection.rb:33:32:33:37 | call to params : | ActiveRecordInjection.rb:33:23:33:45 | "id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:33:32:33:37 | call to params | a user-provided value |
| ActiveRecordInjection.rb:37:16:37:21 | <<-SQL | ActiveRecordInjection.rb:38:21:38:26 | call to params : | ActiveRecordInjection.rb:37:16:37:21 | <<-SQL | This SQL query depends on $@. | ActiveRecordInjection.rb:38:21:38:26 | call to params | a user-provided value |
| ActiveRecordInjection.rb:44:20:44:47 | "user.id = '#{...}'" | ActiveRecordInjection.rb:44:34:44:39 | call to params : | ActiveRecordInjection.rb:44:20:44:47 | "user.id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:44:34:44:39 | call to params | a user-provided value |
| ActiveRecordInjection.rb:60:21:60:33 | ... + ... | ActiveRecordInjection.rb:54:10:54:15 | call to params : | ActiveRecordInjection.rb:60:21:60:33 | ... + ... | This SQL query depends on $@. | ActiveRecordInjection.rb:54:10:54:15 | call to params | a user-provided value |
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:56:23:56:28 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:56:23:56:28 | call to params | a user-provided value |
| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:56:38:56:43 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:56:38:56:43 | call to params | a user-provided value |
| ActiveRecordInjection.rb:23:17:23:25 | condition | ActiveRecordInjection.rb:94:22:94:27 | call to params : | ActiveRecordInjection.rb:23:17:23:25 | condition | This SQL query depends on $@. | ActiveRecordInjection.rb:94:22:94:27 | call to params | a user-provided value |
| ActiveRecordInjection.rb:35:30:35:44 | ...[...] | ActiveRecordInjection.rb:35:30:35:35 | call to params : | ActiveRecordInjection.rb:35:30:35:44 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:35:30:35:35 | call to params | a user-provided value |
| ActiveRecordInjection.rb:39:21:39:43 | "id = '#{...}'" | ActiveRecordInjection.rb:39:30:39:35 | call to params : | ActiveRecordInjection.rb:39:21:39:43 | "id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:39:30:39:35 | call to params | a user-provided value |
| ActiveRecordInjection.rb:43:23:43:45 | "id = '#{...}'" | ActiveRecordInjection.rb:43:32:43:37 | call to params : | ActiveRecordInjection.rb:43:23:43:45 | "id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:43:32:43:37 | call to params | a user-provided value |
| ActiveRecordInjection.rb:47:16:47:21 | <<-SQL | ActiveRecordInjection.rb:48:21:48:26 | call to params : | ActiveRecordInjection.rb:47:16:47:21 | <<-SQL | This SQL query depends on $@. | ActiveRecordInjection.rb:48:21:48:26 | call to params | a user-provided value |
| ActiveRecordInjection.rb:54:20:54:47 | "user.id = '#{...}'" | ActiveRecordInjection.rb:54:34:54:39 | call to params : | ActiveRecordInjection.rb:54:20:54:47 | "user.id = '#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:54:34:54:39 | call to params | a user-provided value |
| ActiveRecordInjection.rb:68:21:68:33 | ... + ... | ActiveRecordInjection.rb:62:10:62:15 | call to params : | ActiveRecordInjection.rb:68:21:68:33 | ... + ... | This SQL query depends on $@. | ActiveRecordInjection.rb:62:10:62:15 | call to params | a user-provided value |