Ответ 1
TL; DR
Что касается ввода и запросов пользователя: Обязательно всегда используйте методы запросов активной записи (например, .where
) и избегайте пропускать параметры с использованием интерполяции строк; передавать их как значения хэш-параметров или в качестве параметризованных операторов.
Относительно рендеринга потенциально небезопасного содержимого html/javascript, создаваемого пользователем. Как и в случае с Rails 3, текст html/javascript автоматически экранируется автоматически, поэтому он отображается как обычный текст на странице, а не интерпретируется как html/javascript, поэтому вам не нужно явно дезинфицировать (или использовать <%= h(potentially_unsafe_user_generated_content)
% >
Если я правильно вас понимаю, вам не нужно беспокоиться о дезинфекции данных таким образом, если вы правильно используете методы запросов активной записи. Например:
Давайте скажем, что наша карта параметров выглядит так, в результате того, что злоумышленник вводит следующую строку в поле user_name
:
:user_name => "(select user_name from users limit 1)"
Плохой путь (не делайте этого):
Users.where("user_name = #{params[:id}") # string interpolation is bad here
Результирующий запрос будет выглядеть так:
SELECT `users`.* FROM `users` WHERE (user_name = (select user_name from users limit 1))
Прямая интерполяция строк таким образом помещает литеральное содержимое значения параметра с ключом :user_name
в запрос без дезинфекции. Как вы, вероятно, знаете, вредоносный ввод пользователя рассматривается как простой SQL-код, и опасность довольно ясна.
Хороший способ (сделайте это):
Users.where(id: params[:id]) # hash parameters
ИЛИ
Users.where("id = ?", params[:id]) # parameterized statement
Результирующий запрос будет выглядеть так:
SELECT `users`.* FROM `users` WHERE user_name = '(select user_name from users limit 1)'
Итак, как вы можете видеть, Rails на самом деле дезориентирует его для вас, пока вы передаете параметр в виде хэша или параметра метода (в зависимости от того, какой метод запроса вы используете).
Случай для дезинфекции данных о создании новых записей модели на самом деле не применяется, поскольку методы new
или create
ожидают хеш значений. Даже если вы попытаетесь ввести небезопасный код SQL в хеш, значения хеша обрабатываются как простые строки, например:
User.create(:user_name=>"bobby tables); drop table users;")
Результаты запроса:
INSERT INTO `users` (`user_name`) VALUES ('bobby tables); drop table users;')
Итак, такая же ситуация, как и выше.
Надеюсь, это поможет. Дайте мне знать, если я пропустил или что-то не понял.
Edit
Что касается экранирования html и javascript, то короткая версия - это то, что ERB "ускользает" от вашего строкового содержимого, так что он рассматривается как обычный текст. Вы можете обработать его как html, если вы действительно этого хотите, выполнив your_string_content.html_safe
.
Однако просто делать что-то вроде <%= your_string_content %>
совершенно безопасно. Содержимое рассматривается как строка на странице. Фактически, если вы изучите DOM с помощью инструментов разработчика Chrome или Firebug, вы должны фактически просмотреть кавычки вокруг этой строки.