smart search: schema-qualify the pgvector <=> operator
because switchman doesn't keep `public` in the search path refs ADV-22 Change-Id: I11ac81ce3a85ffd91912258c5e2f319cf1cce8a3 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/327641 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Jacob Burroughs <jburroughs@instructure.com> QA-Review: Jeremy Stanley <jeremy@instructure.com> Product-Review: Jeremy Stanley <jeremy@instructure.com>
This commit is contained in:
parent
613c65da4a
commit
159b76a9c3
|
@ -46,7 +46,7 @@ class SmartSearchController < ApplicationController
|
||||||
# TODO: Prevent duplicates after chunking embeddings is implemented
|
# TODO: Prevent duplicates after chunking embeddings is implemented
|
||||||
# TODO: Paginate and remove the hardcoded limit (ADV-23)
|
# TODO: Paginate and remove the hardcoded limit (ADV-23)
|
||||||
sql = <<-SQL.squish
|
sql = <<-SQL.squish
|
||||||
SELECT wp.*, (wpe.embedding <=> ?) AS distance
|
SELECT wp.*, (wpe.embedding #{quoted_operator_name("<=>")} ?) AS distance
|
||||||
FROM #{WikiPage.quoted_table_name} wp
|
FROM #{WikiPage.quoted_table_name} wp
|
||||||
INNER JOIN #{Enrollment.quoted_table_name} AS e
|
INNER JOIN #{Enrollment.quoted_table_name} AS e
|
||||||
ON wp.context_type = 'Course'
|
ON wp.context_type = 'Course'
|
||||||
|
@ -76,4 +76,10 @@ class SmartSearchController < ApplicationController
|
||||||
render_unauthorized_action unless OpenAi.smart_search_available?(@domain_root_account)
|
render_unauthorized_action unless OpenAi.smart_search_available?(@domain_root_account)
|
||||||
# TODO: Add state required for new page render
|
# TODO: Add state required for new page render
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def quoted_operator_name(operator)
|
||||||
|
"operator(#{PG::Connection.quote_ident(ActiveRecord::Base.connection.extension("vector").schema)}.#{operator})"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/account.rb",
|
"file": "app/models/account.rb",
|
||||||
"line": 1047,
|
"line": 1062,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "Account.connection.select_values(\"WITH RECURSIVE t AS (\\n SELECT * FROM #{Account.quoted_table_name} WHERE id=#{Shard.local_id_for(starting_account_id.parent_account_id).first}\\n UNION\\n SELECT accounts.* FROM #{Account.quoted_table_name} INNER JOIN t ON accounts.id=t.parent_account_id\\n)\\nSELECT id FROM t\\n\".squish)",
|
"code": "Account.connection.select_values(\"WITH RECURSIVE t AS (\\n SELECT * FROM #{Account.quoted_table_name} WHERE id=#{Shard.local_id_for(starting_account_id.parent_account_id).first}\\n UNION\\n SELECT accounts.* FROM #{Account.quoted_table_name} INNER JOIN t ON accounts.id=t.parent_account_id\\n)\\nSELECT id FROM t\\n\".squish)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/quizzes/quiz.rb",
|
"file": "app/models/quizzes/quiz.rb",
|
||||||
"line": 1392,
|
"line": 1393,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "Quizzes::QuizSubmission.from(\"( VALUES #{quizzes.map do\n \"(#{q.id})\"\n end.join(\", \")} ) AS s(quiz_id)\")",
|
"code": "Quizzes::QuizSubmission.from(\"( VALUES #{quizzes.map do\n \"(#{q.id})\"\n end.join(\", \")} ) AS s(quiz_id)\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 1026,
|
"line": 1028,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.execute(\"CREATE INDEX \\\"temp_primary_key\\\" ON #{connection.quote_local_table_name(\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)])}(#{connection.quote_column_name(primary_key)})\")",
|
"code": "connection.execute(\"CREATE INDEX \\\"temp_primary_key\\\" ON #{connection.quote_local_table_name(\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)])}(#{connection.quote_column_name(primary_key)})\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -256,7 +256,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/calendar_events_api_controller.rb",
|
"file": "app/controllers/calendar_events_api_controller.rb",
|
||||||
"line": 1251,
|
"line": 1344,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "InstStatsd::Statsd.count(\"account_calendars.modal.enabled_calendars\", params[:enabled_account_calendars].length)",
|
"code": "InstStatsd::Statsd.count(\"account_calendars.modal.enabled_calendars\", params[:enabled_account_calendars].length)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -509,7 +509,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 858,
|
"line": 860,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.execute(\"DECLARE #{\"#{table_name}_in_batches_cursor_#{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql.hash.abs.to_s(36)}\"} CURSOR FOR #{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql}\")",
|
"code": "connection.execute(\"DECLARE #{\"#{table_name}_in_batches_cursor_#{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql.hash.abs.to_s(36)}\"} CURSOR FOR #{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -551,7 +551,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 1060,
|
"line": 1062,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.execute(\"DROP TABLE #{\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)]}\")",
|
"code": "connection.execute(\"DROP TABLE #{\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)]}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -570,7 +570,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/account.rb",
|
"file": "app/models/account.rb",
|
||||||
"line": 1021,
|
"line": 1036,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "Account.find_by_sql(\"WITH RECURSIVE t AS (\\n SELECT * FROM #{Account.quoted_table_name} WHERE id=#{Shard.local_id_for(starting_account_id.parent_account_id).first}\\n UNION\\n SELECT accounts.* FROM #{Account.quoted_table_name} INNER JOIN t ON accounts.id=t.parent_account_id\\n)\\nSELECT * FROM t\\n\".squish)",
|
"code": "Account.find_by_sql(\"WITH RECURSIVE t AS (\\n SELECT * FROM #{Account.quoted_table_name} WHERE id=#{Shard.local_id_for(starting_account_id.parent_account_id).first}\\n UNION\\n SELECT accounts.* FROM #{Account.quoted_table_name} INNER JOIN t ON accounts.id=t.parent_account_id\\n)\\nSELECT * FROM t\\n\".squish)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -593,7 +593,7 @@
|
||||||
"check_name": "Redirect",
|
"check_name": "Redirect",
|
||||||
"message": "Possible unprotected redirect",
|
"message": "Possible unprotected redirect",
|
||||||
"file": "app/controllers/users_controller.rb",
|
"file": "app/controllers/users_controller.rb",
|
||||||
"line": 2273,
|
"line": 2264,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||||
"code": "redirect_to(MediaSourceFetcher.new(CanvasKaltura::ClientV3.new).fetch_preferred_source_url(:media_id => params[:entryId], :file_extension => ((params[:type] or params[:format])), :media_type => params[:media_type]))",
|
"code": "redirect_to(MediaSourceFetcher.new(CanvasKaltura::ClientV3.new).fetch_preferred_source_url(:media_id => params[:entryId], :file_extension => ((params[:type] or params[:format])), :media_type => params[:media_type]))",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -639,7 +639,7 @@
|
||||||
"check_name": "SSLVerify",
|
"check_name": "SSLVerify",
|
||||||
"message": "SSL certificate verification was bypassed",
|
"message": "SSL certificate verification was bypassed",
|
||||||
"file": "gems/canvas_kaltura/lib/canvas_kaltura/kaltura_client_v3.rb",
|
"file": "gems/canvas_kaltura/lib/canvas_kaltura/kaltura_client_v3.rb",
|
||||||
"line": 393,
|
"line": 395,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/ssl_verification_bypass/",
|
"link": "https://brakemanscanner.org/docs/warning_types/ssl_verification_bypass/",
|
||||||
"code": "Net::HTTP.new(\"www.kaltura.com\", (if (CanvasKaltura::ClientV3.config[\"protocol\"] != \"http\") then\n Net::HTTP.https_default_port\nelse\n Net::HTTP.http_default_port\nend)).verify_mode = OpenSSL::SSL::VERIFY_NONE",
|
"code": "Net::HTTP.new(\"www.kaltura.com\", (if (CanvasKaltura::ClientV3.config[\"protocol\"] != \"http\") then\n Net::HTTP.https_default_port\nelse\n Net::HTTP.http_default_port\nend)).verify_mode = OpenSSL::SSL::VERIFY_NONE",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -685,7 +685,7 @@
|
||||||
"check_name": "Redirect",
|
"check_name": "Redirect",
|
||||||
"message": "Possible unprotected redirect",
|
"message": "Possible unprotected redirect",
|
||||||
"file": "app/controllers/courses_controller.rb",
|
"file": "app/controllers/courses_controller.rb",
|
||||||
"line": 3406,
|
"line": 3407,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||||
"code": "redirect_to((params[:continue_to] or course_url(@course)))",
|
"code": "redirect_to((params[:continue_to] or course_url(@course)))",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -708,7 +708,7 @@
|
||||||
"check_name": "SendFile",
|
"check_name": "SendFile",
|
||||||
"message": "Model attribute used in file name",
|
"message": "Model attribute used in file name",
|
||||||
"file": "app/controllers/files_controller.rb",
|
"file": "app/controllers/files_controller.rb",
|
||||||
"line": 1539,
|
"line": 1545,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/file_access/",
|
"link": "https://brakemanscanner.org/docs/warning_types/file_access/",
|
||||||
"code": "send_file(Thumbnail.where(:id => params[:id], :uuid => params[:uuid]).first.full_filename, :content_type => Thumbnail.where(:id => params[:id], :uuid => params[:uuid]).first.content_type)",
|
"code": "send_file(Thumbnail.where(:id => params[:id], :uuid => params[:uuid]).first.full_filename, :content_type => Thumbnail.where(:id => params[:id], :uuid => params[:uuid]).first.content_type)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -844,7 +844,7 @@
|
||||||
"check_name": "Redirect",
|
"check_name": "Redirect",
|
||||||
"message": "Possible unprotected redirect",
|
"message": "Possible unprotected redirect",
|
||||||
"file": "app/controllers/users_controller.rb",
|
"file": "app/controllers/users_controller.rb",
|
||||||
"line": 2463,
|
"line": 2454,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||||
"code": "redirect_to(User.avatar_fallback_url(Shard.shard_for(Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).activate do\n Rails.cache.fetch(Cacher.avatar_cache_key(Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id])), ((request.env[\"canvas.domain_root_account\"] or LoadAccount.default_domain_root_account).settings[:avatars] or \"enabled\"))) do\n user = User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first\nif User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first then\n User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first.avatar_url(nil, ((request.env[\"canvas.domain_root_account\"] or LoadAccount.default_domain_root_account).settings[:avatars] or \"enabled\"))\nelse\n \"/images/messages/avatar-50.png\"\nend\n end\n end, request))",
|
"code": "redirect_to(User.avatar_fallback_url(Shard.shard_for(Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).activate do\n Rails.cache.fetch(Cacher.avatar_cache_key(Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id])), ((request.env[\"canvas.domain_root_account\"] or LoadAccount.default_domain_root_account).settings[:avatars] or \"enabled\"))) do\n user = User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first\nif User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first then\n User.where(:id => Shard.global_id_for(User.user_id_from_avatar_key(params[:user_id]))).first.avatar_url(nil, ((request.env[\"canvas.domain_root_account\"] or LoadAccount.default_domain_root_account).settings[:avatars] or \"enabled\"))\nelse\n \"/images/messages/avatar-50.png\"\nend\n end\n end, request))",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -860,6 +860,29 @@
|
||||||
],
|
],
|
||||||
"note": ""
|
"note": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"warning_type": "SQL Injection",
|
||||||
|
"warning_code": 0,
|
||||||
|
"fingerprint": "8ddd54b324d84f7db45c1f45295d77be2449745f9fdfc87bf3e2621302576aa7",
|
||||||
|
"check_name": "SQL",
|
||||||
|
"message": "Possible SQL injection",
|
||||||
|
"file": "app/controllers/smart_search_controller.rb",
|
||||||
|
"line": 67,
|
||||||
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
|
"code": "WikiPage.find_by_sql([\" SELECT wp.*, (wpe.embedding #{quoted_operator_name(\"<=>\")} ?) AS distance\\n FROM #{WikiPage.quoted_table_name} wp\\n INNER JOIN #{Enrollment.quoted_table_name} AS e\\n ON wp.context_type = 'Course'\\n AND wp.context_id = e.course_id\\n INNER JOIN #{EnrollmentState.quoted_table_name} AS es\\n ON e.id = es.enrollment_id\\n INNER JOIN #{WikiPageEmbedding.quoted_table_name} AS wpe\\n ON wp.id = wpe.wiki_page_id\\n WHERE\\n e.user_id = ?\\n AND e.workflow_state <> 'deleted'\\n AND es.restricted_access = FALSE\\n AND es.state IN ('active', 'invited', 'pending_invited', 'pending_active')\\n AND e.type IN ('TeacherEnrollment', 'TaEnrollment', 'DesignerEnrollment', 'StudentViewEnrollment')\\n ORDER BY distance asc\\n LIMIT 25\\n\".squish, OpenAi.generate_embedding(params[:q])[0].to_s, ((((nil or PseudonymSession.find_with_validation.record) or Pseudonym.where(:id => (@policy_pseudonym_id)).first).user or nil) or api_find(User, session[:become_user_id])).id])",
|
||||||
|
"render_path": null,
|
||||||
|
"location": {
|
||||||
|
"type": "method",
|
||||||
|
"class": "SmartSearchController",
|
||||||
|
"method": "index"
|
||||||
|
},
|
||||||
|
"user_input": "quoted_operator_name(\"<=>\")",
|
||||||
|
"confidence": "Medium",
|
||||||
|
"cwe_id": [
|
||||||
|
89
|
||||||
|
],
|
||||||
|
"note": "no user input is interpolated"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"warning_type": "SQL Injection",
|
"warning_type": "SQL Injection",
|
||||||
"warning_code": 0,
|
"warning_code": 0,
|
||||||
|
@ -890,7 +913,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/accounts_controller.rb",
|
"file": "app/controllers/accounts_controller.rb",
|
||||||
"line": 1212,
|
"line": 1270,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "AccountReport.from(\"unnest('{#{AccountReport.available_reports.keys.join(\",\")}}'::text[]) report_types (name),\\n LATERAL (#{@account.account_reports.active.where(\"report_type=name\").most_recent.to_sql}) account_reports \")",
|
"code": "AccountReport.from(\"unnest('{#{AccountReport.available_reports.keys.join(\",\")}}'::text[]) report_types (name),\\n LATERAL (#{@account.account_reports.active.where(\"report_type=name\").most_recent.to_sql}) account_reports \")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -959,7 +982,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/assignment_override.rb",
|
"file": "app/models/assignment_override.rb",
|
||||||
"line": 310,
|
"line": 325,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "where(\"#{field}_overridden\" => true)",
|
"code": "where(\"#{field}_overridden\" => true)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -982,7 +1005,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/conversations_controller.rb",
|
"file": "app/controllers/conversations_controller.rb",
|
||||||
"line": 1064,
|
"line": 1069,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "InstStatsd::Statsd.count(\"inbox.conversation.unstarred.legacy\", params[:conversation_ids].length)",
|
"code": "InstStatsd::Statsd.count(\"inbox.conversation.unstarred.legacy\", params[:conversation_ids].length)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1005,7 +1028,7 @@
|
||||||
"check_name": "UnsafeReflection",
|
"check_name": "UnsafeReflection",
|
||||||
"message": "Unsafe reflection method `const_get` called with parameter value",
|
"message": "Unsafe reflection method `const_get` called with parameter value",
|
||||||
"file": "app/controllers/application_controller.rb",
|
"file": "app/controllers/application_controller.rb",
|
||||||
"line": 1429,
|
"line": 1464,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/remote_code_execution/",
|
"link": "https://brakemanscanner.org/docs/warning_types/remote_code_execution/",
|
||||||
"code": "Object.const_get((params[:feed_code].split(\"_\", 2) or [\"group_membership\", params[:feed_code].split(\"_\", 3)[-1]])[0].classify, false)",
|
"code": "Object.const_get((params[:feed_code].split(\"_\", 2) or [\"group_membership\", params[:feed_code].split(\"_\", 3)[-1]])[0].classify, false)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1028,7 +1051,7 @@
|
||||||
"check_name": "RegexDoS",
|
"check_name": "RegexDoS",
|
||||||
"message": "Model attribute used in regular expression",
|
"message": "Model attribute used in regular expression",
|
||||||
"file": "app/models/course.rb",
|
"file": "app/models/course.rb",
|
||||||
"line": 2715,
|
"line": 2776,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
||||||
"code": "/\\A#{(Folder.root_folders(self).first.name + \"/\")}/",
|
"code": "/\\A#{(Folder.root_folders(self).first.name + \"/\")}/",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1052,7 +1075,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/accounts_controller.rb",
|
"file": "app/controllers/accounts_controller.rb",
|
||||||
"line": 1207,
|
"line": 1265,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "AccountReport.from(\"unnest('{#{AccountReport.available_reports.keys.join(\",\")}}'::text[]) report_types (name),\\n LATERAL (#{@account.account_reports.active.where(\"report_type=name\").most_recent.complete.to_sql}) account_reports \")",
|
"code": "AccountReport.from(\"unnest('{#{AccountReport.available_reports.keys.join(\",\")}}'::text[]) report_types (name),\\n LATERAL (#{@account.account_reports.active.where(\"report_type=name\").most_recent.complete.to_sql}) account_reports \")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1374,7 +1397,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/conversations_controller.rb",
|
"file": "app/controllers/conversations_controller.rb",
|
||||||
"line": 1063,
|
"line": 1068,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "InstStatsd::Statsd.count(\"inbox.conversation.starred.legacy\", params[:conversation_ids].length)",
|
"code": "InstStatsd::Statsd.count(\"inbox.conversation.starred.legacy\", params[:conversation_ids].length)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1397,7 +1420,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 881,
|
"line": 883,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.execute(\"CLOSE #{cursor}\")",
|
"code": "connection.execute(\"CLOSE #{cursor}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1416,7 +1439,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/student_enrollment.rb",
|
"file": "app/models/student_enrollment.rb",
|
||||||
"line": 88,
|
"line": 95,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "Submission.joins(:assignment).where(:user_id => students.map(&:user_id), :workflow_state => \"deleted\", :assignments => ({ :context_id => course_id })).merge(Assignment.active).in_batches.update_all(\"workflow_state = #{SubmissionLifecycleManager.infer_submission_workflow_state_sql}\")",
|
"code": "Submission.joins(:assignment).where(:user_id => students.map(&:user_id), :workflow_state => \"deleted\", :assignments => ({ :context_id => course_id })).merge(Assignment.active).in_batches.update_all(\"workflow_state = #{SubmissionLifecycleManager.infer_submission_workflow_state_sql}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1439,7 +1462,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/controllers/conversations_controller.rb",
|
"file": "app/controllers/conversations_controller.rb",
|
||||||
"line": 1065,
|
"line": 1070,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "InstStatsd::Statsd.count(\"inbox.conversation.unread.legacy\", params[:conversation_ids].length)",
|
"code": "InstStatsd::Statsd.count(\"inbox.conversation.unread.legacy\", params[:conversation_ids].length)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1508,7 +1531,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 1029,
|
"line": 1031,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.execute(\"ALTER TABLE #{\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)]} ADD temp_primary_key SERIAL PRIMARY KEY\")",
|
"code": "connection.execute(\"ALTER TABLE #{\"#{table_name}_in_batches_temp_table_#{apply_limits(self, start, finish, order).to_sql.hash.abs.to_s(36)}\"[(-63..)]} ADD temp_primary_key SERIAL PRIMARY KEY\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1527,7 +1550,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 868,
|
"line": 870,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.select_values(\"FETCH FORWARD #{of} FROM #{\"#{table_name}_in_batches_cursor_#{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql.hash.abs.to_s(36)}\"}\")",
|
"code": "connection.select_values(\"FETCH FORWARD #{of} FROM #{\"#{table_name}_in_batches_cursor_#{apply_limits(clone, start, finish, order).except(:select).select(primary_key).to_sql.hash.abs.to_s(36)}\"}\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1546,7 +1569,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "config/initializers/active_record.rb",
|
"file": "config/initializers/active_record.rb",
|
||||||
"line": 1579,
|
"line": 1581,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "connection.select_value(\"SELECT COUNT(*) FROM pg_proc WHERE proname='#{procname}'\")",
|
"code": "connection.select_value(\"SELECT COUNT(*) FROM pg_proc WHERE proname='#{procname}'\")",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1661,7 +1684,7 @@
|
||||||
"check_name": "RegexDoS",
|
"check_name": "RegexDoS",
|
||||||
"message": "Model attribute used in regular expression",
|
"message": "Model attribute used in regular expression",
|
||||||
"file": "app/models/content_migration.rb",
|
"file": "app/models/content_migration.rb",
|
||||||
"line": 604,
|
"line": 603,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
||||||
"code": "/\\A#{(Folder.root_folders(context).first.name + \"/\")}/",
|
"code": "/\\A#{(Folder.root_folders(context).first.name + \"/\")}/",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -1702,6 +1725,6 @@
|
||||||
"note": ""
|
"note": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"updated": "2023-06-23 20:34:01 +0000",
|
"updated": "2023-09-13 14:16:05 -0600",
|
||||||
"brakeman_version": "5.4.1"
|
"brakeman_version": "6.0.1"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue