@@ -18,6 +18,15 @@ private class ApplicationRecordAccess extends ConstantReadAccess {
1818 ApplicationRecordAccess ( ) { this .getName ( ) = "ApplicationRecord" }
1919}
2020
21+ /**
22+ * A `ClassDeclaration` for a class that extends `ActiveRecord::Base`. For example,
23+ *
24+ * ```rb
25+ * class UserGroup < ActiveRecord::Base
26+ * has_many :users
27+ * end
28+ * ```
29+ */
2130class ActiveRecordModelClass extends ClassDeclaration {
2231 ActiveRecordModelClass ( ) {
2332 // class Foo < ActiveRecord::Base
@@ -33,7 +42,7 @@ class ActiveRecordModelClass extends ClassDeclaration {
3342 }
3443}
3544
36- // A class method call whose receiver is an ActiveRecord model class
45+ /** A class method call whose receiver is an `ActiveRecordModelClass`. */
3746class ActiveRecordModelClassMethodCall extends MethodCall {
3847 // The model class that receives this call, if any
3948 private ActiveRecordModelClass recvCls ;
@@ -64,6 +73,20 @@ private predicate methodWithSqlFragmentArg(string methodName, int argIndex) {
6473 methodName = "calculate" and argIndex = 1
6574}
6675
76+ /**
77+ * A method call that may result in executing unintended user-controlled SQL
78+ * queries if the `getSqlFragmentSinkArgument()` expression is tainted by
79+ * unsanitized user-controlled input. For example, supposing that `User` is an
80+ * `ActiveRecord` model class, then
81+ *
82+ * ```rb
83+ * User.where("name = '#{user_name}'")
84+ * ```
85+ *
86+ * may be unsafe if `user_name` is from unsanitized user input, as a value such
87+ * as `"') OR 1=1 --"` could result in the application looking up all users
88+ * rather than just one with a matching name.
89+ */
6790class PotentiallyUnsafeSqlExecutingMethodCall extends ActiveRecordModelClassMethodCall {
6891 // The name of the method invoked
6992 private string methodName ;
@@ -94,6 +117,11 @@ class PotentiallyUnsafeSqlExecutingMethodCall extends ActiveRecordModelClassMeth
94117 Expr getSqlFragmentSinkArgument ( ) { result = sqlFragmentExpr }
95118}
96119
120+ /**
121+ * An `SqlExecution::Range` for an argument to a
122+ * `PotentiallyUnsafeSqlExecutingMethodCall` that may be vulnerable to being
123+ * controlled by user input.
124+ */
97125class ActiveRecordSqlExecutionRange extends SqlExecution:: Range {
98126 ActiveRecordSqlExecutionRange ( ) {
99127 exists ( PotentiallyUnsafeSqlExecutingMethodCall mc |
0 commit comments