CVE-2015-2972 (Ruby, published 2015-07-19T15:59Z)
Description: value: Multiple SQL injection vulnerabilities in Sysphonic Thetis before 2.3.0 allow remote attackers to execute arbitrary SQL commands via unspecified vectors.
Severity: HIGH (CVSS v3 base score: )
Weakness: CWE-89 \u2014 Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Repository: https://github.com/sysphonic/thetis
Files changed:
app/controllers/application_controller.rb
app/controllers/mail_filters_controller.rb
app/controllers/mail_folders_controller.rb
app/controllers/workflows_controller.rb
app/helpers/mail_filters_helper.rb
app/models/address.rb
app/models/comment.rb
app/models/email.rb
app/models/item.rb
app/models/toy.rb
app/models/user.rb
app/views/mail_filters/_mail_filter_form.html.erb
Commit message: Reinforcement of security.
Signed-off-by: MORITA Shintaro <shin@sysphonic.com>


Vulnerable code:
    if options[:count]
      else
        total = model.count_by_sql(options[:count])
    else
      total = model.count_by_sql_wrapping_select_query(sql)
    #objects = model.find_by_sql_with_limit(sql, object_pages.current.to_sql[1], per_page)
    @login_user = User.find_by_id(session[:login_user_id])
    def self.find_by_sql_with_limit(sql, offset, limit)
      sql = sanitize_sql(sql)
      add_limit!(sql, {:limit => limit, :offset => offset})
      find_by_sql(sql)
    end

    @mail_filter = MailFilter.find_by_id(params[:id])
    mail_account = MailAccount.find_by_id(params[:mail_account_id])
    mail_folder = MailFolder.find_by_id(params[:mail_folder_id])
    @mail_account = MailAccount.find_by_id(mail_account_id)
    order_ary = params[:mail_filters_order]
    @mail_account = MailAccount.find_by_id(mail_account_id)
      idx_a = order_ary.index(id_a)
      idx_b = order_ary.index(id_b)
    email = Email.find_by_id(email_id)
    mail_attach = MailAttachment.find_by_id(attached_id)
    email = Email.find_by_id(mail_attach.email_id)
        email = Email.find_by_id(email_id)
    mail_folder = MailFolder.find_by_id(folder_id)
    order_ary = params[:folders_order]
      idx_a = order_ary.index(id_a)
      idx_b = order_ary.index(id_b)
    mail_folder = MailFolder.find_by_id(mail_folder_id)
    unless imp_id.nil? or imp_id.empty?
          group = Group.find_by_id(group_id)
          team = Team.find_by_id(team_id)
    attachments = [] if attachments.nil?
    return attachments

      mail_account = MailAccount.find_by_id(email.mail_account_id)
    src_item = Item.find_by_id(self.source_id)
    deleted_ary = []
            deleted_ary << toy
            deleted_ary << toy
            deleted_ary << toy
            deleted_ary << toy
            deleted_ary << toy
    deleted_ary.each do |toy|
      toys.delete toy
      Toy.destroy toy.id
          group = Group.find_by_id(group_id)
mail_account = MailAccount.find_by_id(mail_account_id)

Fixed code:
    if options[:count].blank?
      total = model.count_by_sql_wrapping_select_query(sql)
    else
      #else
      #  total = model.count_by_sql(options[:count])
    SqlHelper.validate_token([params['page']])
    @login_user = User.find(session[:login_user_id])
    begin
      @mail_filter = MailFilter.find(params[:id])
    rescue => evar
    end
    mail_account = MailAccount.find(params[:mail_account_id])
    mail_folder = MailFolder.find(params[:mail_folder_id])
    SqlHelper.validate_token([mail_account_id])
    @mail_account = MailAccount.find(mail_account_id)
    order_arr = params[:mail_filters_order]

    SqlHelper.validate_token([mail_account_id])
    @mail_account = MailAccount.find(mail_account_id)
      idx_a = order_arr.index(id_a)
      idx_b = order_arr.index(id_b)
    email = Email.find(email_id)
    begin
      mail_attach = MailAttachment.find(attached_id)
    rescue => evar
    end
    begin
      email = Email.find(mail_attach.email_id)
    rescue => evar
    end
        begin
          email = Email.find(email_id)
        rescue => evar
        end
    SqlHelper.validate_token([folder_id])
    begin
      mail_folder = MailFolder.find(folder_id)
    rescue => evar
    end
    order_arr = params[:folders_order]
    SqlHelper.validate_token([params[:id]])
      idx_a = order_arr.index(id_a)
      idx_b = order_arr.index(id_b)
      SqlHelper.validate_token([folder_id])
    SqlHelper.validate_token([mail_folder_id])
    begin
      mail_folder = MailFolder.find(mail_folder_id)
    rescue => evar
    end
    SqlHelper.validate_token([imp_id])
    unless imp_id.blank?
          begin
            group = Group.find(group_id)
          rescue => evar
            group = nil
          end
          begin
            team = Team.find(team_id)
          rescue => evar
            team = nil
          end
    return (attachments || [])
      mail_account = MailAccount.find(email.mail_account_id)
    begin
      src_item = Item.find(self.source_id)
    rescue => evar
      src_item = nil
    end
    deleted_arr = []
            deleted_arr << toy
            deleted_arr << toy
            deleted_arr << toy
            deleted_arr << toy
            deleted_arr << toy
    deleted_arr.each do |toy|
      toys.delete(toy)
      Toy.destroy(toy.id)
          begin
            group = Group.find(group_id)
          rescue => evar
            group = nil
          end
SqlHelper.validate_token([mail_account_id])
mail_account = MailAccount.find(mail_account_id)