GORMは、SQL文を構築するためにdatabase/sql
の引数プレースホルダーを使用しており、SQLインジェクションを回避するために引数を自動的にエスケープします。
注意 ロガーからのSQLは、実行されるもののように完全にエスケープされていません。SQLコンソールでコピーして実行する際には注意してください。
クエリ条件
ユーザーの入力は、例えば以下のように引数としてのみ使用する必要があります。
userInput := "jinzhu;drop table users;"
db.Where("name = ?", userInput).First(&user)
db.Where(fmt.Sprintf("name = %v", userInput)).First(&user)
|
インライン条件
db.First(&user, "name = ?", userInput)
db.First(&user, fmt.Sprintf("name = %v", userInput))
|
ユーザーの入力によって数値の主キーを持つオブジェクトを取得する際、変数の型を確認する必要があります。
userInputID := "1=1;drop table users;"
id, err := strconv.Atoi(userInputID) if err != nil { return err } db.First(&user, id)
db.First(&user, userInputID)
|
SQLインジェクション手法
いくつかの機能をサポートするために、いくつかの入力はエスケープされません。これらのメソッドでユーザーの入力を使用する際には注意してください。
db.Select("name; drop table users;").First(&user) db.Distinct("name; drop table users;").First(&user)
db.Model(&user).Pluck("name; drop table users;", &names)
db.Group("name; drop table users;").First(&user)
db.Group("name").Having("1 = 1;drop table users;").First(&user)
db.Raw("select name from users; drop table users;").First(&user)
db.Exec("select name from users; drop table users;")
db.Order("name; drop table users;").First(&user)
|
SQLインジェクションを回避するための一般的なルールは、ユーザーが送信したデータを信頼しないことです。ユーザー入力を既知の、承認された、定義された入力のセットに対してテストするために、ホワイトリスト検証を実行できます。また、ユーザー入力を使用する場合は、それらを引数としてのみ使用してください。