Безопасные запросы вставки с помощью go-sql-driver и mysql - PullRequest
0 голосов
/ 02 октября 2019

Я рассмотрел примеры go-sql-драйвера с помощью db.Prepare, но я не смог заставить его работать должным образом, поэтому я изменил его для работы напрямую с db.Query. Я понимаю, что с помощью ?? значение в любом случае экранируется, поэтому мне было интересно, правильно ли и безопасно ли следующее для внедрения SQL-кода (обратите внимание, что я использую MySQL)

stmtIns, err := db.Query("INSERT INTO users (name, address) VALUES(?,?)", name, address) // ? = placeholder
        if err != nil {
            panic(err.Error()) // proper error handling instead of panic in your app
        }
        defer stmtIns.Close() // Close the statement when we leave main() / the program terminates

Кроме того, каков наилучший способ определить, была ли строкавставить?

уточнение: для безопасности я имел в виду SQL Injection. Я думаю, что это так, но потом я удивляюсь, почему все примеры, которые я смог найти, используют db.Prepare, а не db.Query, как я.

1 Ответ

1 голос
/ 02 октября 2019

Да, это безопасно от атак с использованием SQL-инъекций.

Обратите внимание, что клиентский код не"экранирует" параметры в запросе такого рода. Он делает что-то намного проще и безопаснее:

Клиент не объединяет INSERT INTO users (name) VALUES(?) и параметр ;DROP TABLE USERS; в INSERT INTO users (name) VALUES(;DROP TABLE USERS;.

Также клиент не выполняет вышеуказанное с помощью escape-символовсделать это "безопасным". Клиент не создает что-то вроде INSERT INTO users (name) VALUES("\;DROP TABLE USERS\;")

Что он делает, это отправляет запрос в MySQL, который отдельно содержит:

  • строка запроса INSERT INTO users (name) VALUES(?) - MySQL знает, что это строка запроса, и знает, что ? - это место, где подключены параметры.
  • параметр ;DROP TABLE USERS; - MySQL знает, что это параметр запроса

Следовательно, сервер знает, что этот параметр не является кодом SQL, и что аккуратно избегает всей неприятной проблемы с экранированием символов.

Если вы не используете Prepare, выпропускают некоторый потенциал для оптимизации на сервере. Сервер компилирует каждый оператор во внутреннее представление, и это требует времени. Делая это явно и повторно используя подготовленный оператор, вы явно сохраняете повторение этого шага компиляции.

Однако MySQL делает кешированные скомпилированные операторы, чтобы избежать повторной компиляции одной и той же строки - так что вы, вероятно, не будетеувидеть большие проблемы с производительностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...