Pull to refresh

Comments 8

Мы же говорим о действительно сложных запросах, так? Вот немного притянутый за уши контр-пример, но проблема, думаю, понятна:
sql = 'SELECT id, name::varchar FROM schema.news WHERE id=:var'
binding = { var: 100 }
new = SqlQuery.execute(sql, binding).first
Да, согласен, что поимеем проблему. Но согласитесь, что как-то странно именованный биндинг называть :var. Обычно называют исходя из контекста, например news_id. Но тот код что вы привели в пример, действительно может положить постгрес при сборке запроса. Если обертку усложнять и делать защиту от подобных проблем, то мы уже тогда сосредотачиваемся на создании конкретного решения. А мне не очень этого хотелось. Простота залог успеха, но есть нюансы, как вы правильно подметили.
Ну, согласитесь, что когда отлаживаешь сложный запрос с postgis на 20-30 строк, который написал твой предшественник 2 года назад, то такие вот неочевидные тонкости могут оказаться очень неприятным открытием.

Я бы предложил хотя бы делать замены регуляркой типа:
.gsub(/:var(?=\b)/, '$1')
Вот так будет совсем хорошо: sql.gsub!(/(?<!:):#{key}(?=\b)/, "$#{bind_index}") Будем проверять, что слева нет еще одного двоеточия.
UFO just landed and posted this here
sanitize_sql_array сделает подстановку в тексте в обход Postgres. Чувствуете разницу между плейсхолдерами через базу данных и через встроенный метод. Очень многие эксперты по безопасности рекомендуют использовать биндинги только в рамках запроса к базе (на уровне самой базы данных), так как это более безопасно. А так, то конечно, не было бы смысла заморачиваться со своими велосипедами :)
Sign up to leave a comment.

Articles