SQLパラメータ値をsqlパッケージ関数の引数として提供することで、SQLインジェクションリスクを回避できます。sqlパッケージの多くの関数は、SQL文のパラメータとその文のパラメータで使用される値のためのパラメータを提供します(他の関数は、準備されたステートメントとパラメータのためのパラメータを提供します)。

    以下の例のコードは、idパラメータのプレースホルダーとして?シンボルを使用し、関数引数として提供されます:

    1. // Correct format for executing an SQL statement with parameters.
    2. rows, err := db.Query("SELECT * FROM user WHERE id = ?", id)
    1. **注意:** パラメータプレースホルダーは、使用しているDBMSおよびドライバによって異なります。たとえば、Postgres用の[pqドライバ](https://pkg.go.dev/github.com/lib/pq)は、`````?`````の代わりに`````$1`````のようなプレースホルダー形式を受け入れます。
    2. SQL文をパラメータを含む文字列として組み立てるために、`````fmt`````パッケージの関数を使用したくなるかもしれません このように:
    3. ``````bash
    4. // SECURITY RISK!
    5. rows, err := db.Query(fmt.Sprintf("SELECT * FROM user WHERE id = %s", id))
    6. `

    これは安全ではありません!これを行うと、Goは全体のSQL文を組み立て、%sフォーマット動詞をパラメータ値で置き換えた後、完全な文をDBMSに送信します。これは、呼び出し元がid引数として予期しないSQLスニペットを送信する可能性があるため、SQLインジェクションリスクを引き起こします。そのスニペットは、アプリケーションにとって危険な予測不可能な方法でSQL文を完成させる可能性があります。

    たとえば、特定の%s値を渡すことで、次のような結果になる可能性があり、データベース内のすべてのユーザーレコードを返すことができます:

    1. SELECT * FROM user WHERE id = 1 OR 1=1;