#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.