Как правило, вам не следует использовать интерполяцию строк для построения запросов SQL. Это оставит вас открытыми для SQL-инъекций атак, при которых кто-то вводит ввод с закрывающей кавычкой, а затем другой запрос. Например, используя ваш пример:
>> val = '7; DROP TABLE users;'
=> "7; DROP TABLE users;"
>> myQuery = "select * from t where t.val = \#{val}"
=> "select * from t where t.val = \#{val}"
>> eval "\"#{myQuery}\""
=> "select * from t where t.val = 7; DROP TABLE users;"
Даже без злонамеренного ввода вы могли бы просто случайно выполнить код, который вы не собирались делать, если, например, кто-то включил кавычки в свои данные.
Также, как правило, рекомендуется избегать использования eval
без крайней необходимости; это делает возможным, что если у вас есть ошибка в вашей программе, кто-то может выполнить произвольный код, передав его в eval
, и это делает код менее поддерживаемым, так как часть вашего исходного кода будет загружена из мест, отличных от вашего обычного источника дерево.
Итак, как ты это делаешь вместо этого? API базы данных обычно включают команду prepare
, которая может подготовиться к выполнению оператора SQL. В этом выражении вы можете включить ?
символов, которые представляют параметры, которые могут быть заменены в этом выражении. Затем вы можете вызвать execute
в операторе, передав значения для этих параметров, и они будут выполнены безопасно, и никто не сможет выполнить произвольный фрагмент SQL.
Вот как это будет работать в вашем примере. Предполагается, что вы используете этот модуль MySQL / Ruby ; если вы используете другой, он, вероятно, будет иметь похожий интерфейс, хотя он может не совпадать.
>> val = 7
>> db = Mysql.new(hostname, username, password, databasename)
>> query = db.prepare("select * from t where t.val = ?")
>> query.execute(val)