mirror of
https://github.com/github/codeql.git
synced 2026-05-04 13:15:21 +02:00
Merge pull request #196 from github/active-record-1
Start modelling some potential SQL fragment sinks in ActiveRecord
This commit is contained in:
22
ql/test/library-tests/frameworks/ActiveRecord.expected
Normal file
22
ql/test/library-tests/frameworks/ActiveRecord.expected
Normal file
@@ -0,0 +1,22 @@
|
||||
activeRecordModelClasses
|
||||
| ActiveRecordInjection.rb:1:1:3:3 | UserGroup |
|
||||
| ActiveRecordInjection.rb:5:1:7:3 | User |
|
||||
| ActiveRecordInjection.rb:9:1:10:3 | Admin |
|
||||
activeRecordSqlExecutionRanges
|
||||
| ActiveRecordInjection.rb:22:21:22:41 | "id = #{...}" |
|
||||
| ActiveRecordInjection.rb:28:16:28:21 | <<-SQL |
|
||||
| ActiveRecordInjection.rb:32:35:32:60 | "user.id = #{...}" |
|
||||
| ActiveRecordInjection.rb:45:21:45:33 | ... + ... |
|
||||
activeRecordModelClassMethodCalls
|
||||
| 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 |
|
||||
potentiallyUnsafeSqlExecutingMethodCall
|
||||
| ActiveRecordInjection.rb:22:5:22:42 | call to delete_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 |
|
||||
12
ql/test/library-tests/frameworks/ActiveRecord.ql
Normal file
12
ql/test/library-tests/frameworks/ActiveRecord.ql
Normal file
@@ -0,0 +1,12 @@
|
||||
import codeql_ruby.controlflow.CfgNodes
|
||||
import codeql_ruby.frameworks.ActiveRecord
|
||||
|
||||
query predicate activeRecordModelClasses(ActiveRecordModelClass cls) { any() }
|
||||
|
||||
query predicate activeRecordSqlExecutionRanges(ActiveRecordSqlExecutionRange range) { any() }
|
||||
|
||||
query predicate activeRecordModelClassMethodCalls(ActiveRecordModelClassMethodCall call) { any() }
|
||||
|
||||
query predicate potentiallyUnsafeSqlExecutingMethodCall(PotentiallyUnsafeSqlExecutingMethodCall call) {
|
||||
any()
|
||||
}
|
||||
51
ql/test/library-tests/frameworks/ActiveRecordInjection.rb
Normal file
51
ql/test/library-tests/frameworks/ActiveRecordInjection.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class UserGroup < ActiveRecord::Base
|
||||
has_many :users
|
||||
end
|
||||
|
||||
class User < ApplicationRecord
|
||||
belongs_to :user_group
|
||||
end
|
||||
|
||||
class Admin < User
|
||||
end
|
||||
|
||||
class FooController < ActionController::Base
|
||||
|
||||
MAX_USER_ID = 100_000
|
||||
|
||||
# A string tainted by user input is inserted into an SQL query
|
||||
def some_request_handler
|
||||
# SELECT AVG(#{params[:column]}) FROM "users"
|
||||
User.calculate(:average, params[:column])
|
||||
|
||||
# DELETE FROM "users" WHERE (id = #{params[:id]})
|
||||
User.delete_all("id = #{params[:id]}")
|
||||
|
||||
# SELECT "users".* FROM "users" WHERE (id = #{params[:id]})
|
||||
User.destroy_all(["id = #{params[:id]}"])
|
||||
|
||||
# SELECT "users".* FROM "users" WHERE id BETWEEN #{params[:min_id]} AND 100000
|
||||
User.where(<<-SQL, MAX_USER_ID)
|
||||
id BETWEEN #{params[:min_id]} AND ?
|
||||
SQL
|
||||
|
||||
UserGroup.joins(:users).where("user.id = #{params[:id]}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class BarController < ApplicationController
|
||||
|
||||
def some_other_request_handler
|
||||
ps = params
|
||||
|
||||
uid = ps[:id]
|
||||
|
||||
# DELETE FROM "users" WHERE (id = #{uid})
|
||||
User.delete_all("id = " + uid)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class BazController < BarController
|
||||
end
|
||||
Reference in New Issue
Block a user