Внедрение SQL в ActiveRecord

#sql #ruby-on-rails #security #activerecord

#sql #ruby-on-rails #Безопасность #activerecord

Вопрос:

Я пытаюсь создать уязвимое демонстрационное приложение. Я использую SQLite, и у меня есть код ruby, который выглядит следующим образом:

@value = current_user.accounts.calculate(:sum, params[:column])

И SQL по умолчанию генерирует следующее:

User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
(0.1ms) SELECT SUM("accounts"."account_value") AS sum_id FROM "accounts" WHERE "accounts"."user_id" = ? [["user_id", 1]]

Далее я вводю ssn) FROM users WHERE name = 'Texas'; -- в форму и получаю следующее:

 (0.3ms)  SELECT SUM(ssn) FROM users WHERE name = 'Texas'; --)) AS sum_id FROM "accounts"  WHERE "accounts"."user_id" = ?  [["user_id", 1]]
SQLite3::RangeException: bind or column index out of range: SELECT SUM(ssn) FROM users WHERE name = 'Texas'; --)) AS sum_id FROM "accounts"  WHERE "accounts"."user_id" = ?
Completed 500 Internal Server Error in 2ms

ActiveRecord::StatementInvalid (SQLite3::RangeException: bind or column index out of range: SELECT SUM(ssn) FROM users WHERE name = 'Texas'; --)) AS sum_id FROM "accounts"  WHERE "accounts"."user_id" = ?):
  app/controllers/instant_calculator_controller.rb:3:in `sum'
  

Я думаю, проблема в том, что раздел ‘user_id’, прикрепленный к концу в качестве параметризованного запроса, все портит. Я пытался сделать что-то вроде ssn) FROM users WHERE name = 'Texas'OR user_id = ?; -- просто отбросить эту часть запроса, но, похоже, это не помогло.

У кого-нибудь есть какие-либо мысли о том, как я мог бы заставить это работать? Я могу изменить код, а также запрос, но я бы предпочел изменить запрос перед переходом к коду, чтобы сделать его надежным.

Редактировать:

Немного больше информации. Если я возьму сгенерированный SQL и просто изменю последний user_id на ‘1’, чтобы это выглядело так, SELECT SUM(ssn) FROM users WHERE name = 'Texas'; --) AS sum_id FROM 'accounts' WHERE 'accounts'.'user_id' = 1 что все работает идеально. Я не понимаю, почему это имеет значение, поскольку все, что после -- должно быть проигнорировано.

Комментарии:

1. Попробуйте присвоить столбцам имя таблицы. Как user.ssn и user.name

2. @RubyRacer Я получаю сообщение об ошибке `неправильное количество аргументов для функции SUM()`. Это имеет смысл, хотя бы потому, что создаваемый SQL не знает о пользовательском объекте и методе ssn или name.

3. Я совершенно уверен, что если вы вставите производный оператор в консоль sqlite, он сработает, переведя проблему на обработку из AR…

4. @RubyRacer, возможно, я не понимаю тебя. Можете ли вы структурировать sql так, как вы этого хотите, и вставить его, чтобы убедиться, что я не просто невежественен.

5. Если вы откроете свою базу данных sqlite с помощью этой команды из консоли: sqlite3 db/yourdb.sqlite3 и на консоли вы вставите SELECT SUM(ssn) FROM users WHERE name = 'Texas'; --)) AS sum_id FROM "accounts" WHERE "accounts"."user_id" = ? [["user_id", 1]] и нажмете enter, это сработает. Это не работает через Rails, потому что ActiveRecord что-то делает (неопределенное, я не знаю) с запросом, возможно, какую-то очистку, перед отправкой его в адаптер DB.