Защита от вставки SQL с помощью RMySQL

Я пытаюсь реализовать защиту от вставки SQL в операторы выбора SQL, используя RMySQL. Я пытался добавить escape-символ (т. е. обратную косую черту) перед каждым символом риска, т. е. кавычку ("или") или обратную косую черту (\). Я использую функцию RMySQL, dbEscapeStrings, которая похожа на функцию PHP. mysql_real_escape_string функция.

Я подозреваю, что упускаю что-то очень очевидное, но, поскольку MySQL требует, чтобы строки символов в операторе WHERE были заключены в кавычки, использование dbEscapeStrings для применения escape-символов к кавычкам в операторе select вызывает ошибку, блокирующую все строковые запросы, а не только инъекцию атаки. Например,

user <- "'peter'"
tmp <- sprintf("select * from users where username = %s", user)
sql <- dbEscapeStrings(con, tmp)
dbGetQuery(con, sql)

dbEscapeStrings вставляет двойную обратную косую черту перед каждой кавычкой (т. е. полученная переменная sql имеет вид "select * from users where username = \\'peter\\'"), что вызывает синтаксическую ошибку на сервере MySQL. при запуске dbGetQuery.

Любые предложения о том, как заставить работать вышеперечисленное или реализовать альтернативную защиту от вставки SQL с помощью RMySQL? Предусматривает ли RMySQL использование подготовленных операторов, которые могут предотвратить атаки вставкой?


person user2500880    schedule 31.07.2014    source источник
comment
попробуйте mysqlExecStatement(con, tmp, user), а затем mysqlFetch(dbListResults(con)[[1]]). Я предлагаю это на основе того, что я делаю с RPostgreSQL.   -  person Alex    schedule 31.07.2014
comment
Спасибо @Alex за совет по подготовленному заявлению. Это работает хорошо. Я также разработал решение для escape-символа — я знал, что упустил что-то простое — применить dbEscapeStrings к пользователю, а не к tmp, и перед добавлением одинарных кавычек к пользователю.   -  person user2500880    schedule 01.08.2014
comment
@Alex Алекс, я настоятельно рекомендую вам использовать стандартные дженерики БД - mysqlExecStatement() никогда не следовало экспортировать, и в следующей версии они будут устранены.   -  person hadley    schedule 25.02.2015
comment
Спасибо. Что такое стандартные дженерики БД?   -  person Alex    schedule 26.02.2015


Ответы (1)


Самый безопасный (и самый простой) способ - использовать параметризованный запрос (это не доступно в выпуске CRAN, но есть в версии для разработчиков)

dbGetQuery(myconnection, "SELECT * FROM users WHERE username = ?", list(user))
person hadley    schedule 25.02.2015