Go言語でINSERT文を書く時、直接user_idやpriceなどの変数を構文中に入れるとデータを消去されたり改変される危険性がある。

これをSQLインジェクションと呼ぶ。

SQLインジェクション - Wikipedia


SQLインジェクションを阻止するための方法にプリペアドステートメントがある。


例として、下記のようなコードを記載する.

package main

import (
	"database/sql"
	"log"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "sample.db")
	if err != nil {
		log.Fatal(err)
	}
	user_id := 10
	price := 10000

	s := "INSERT INTO orders(user_id,price) VALUES(?,?);"
	stmt, err := db.Prepare(s)
	if err != nil {
		log.Fatal(err)
	}
	_, err := stmt.Exec(user_id, price)
	if err != nil {
		log.Fatal(err)
	}
}

今までだと、s := "INSERT INTO orders(user_id,price) VALUES(" 10","10000");で記載していたのを、VALUESの後を(?,?)に変更する。そのあと、プリペアードステートメントでdb.Prepare(s), stmt.Exec(user_id, price)する。

stmt.Execの()内は、文字に変換せず、そのまま数字を入れることができる。


関連記事

SOY2DAOでプリペアードステートメントを利用する