SQLパラメータ値をsql
パッケージ関数の引数として提供することで、SQLインジェクションリスクを回避できます。sql
パッケージの多くの関数は、SQL文のパラメータとその文のパラメータで使用される値のためのパラメータを提供します(他の関数は、準備されたステートメントとパラメータのためのパラメータを提供します)。
以下の例のコードは、id
パラメータのプレースホルダーとして?
シンボルを使用し、関数引数として提供されます:
// Correct format for executing an SQL statement with parameters.
rows, err := db.Query("SELECT * FROM user WHERE id = ?", id)
**注意:** パラメータプレースホルダーは、使用しているDBMSおよびドライバによって異なります。たとえば、Postgres用の[pqドライバ](https://pkg.go.dev/github.com/lib/pq)は、`````?`````の代わりに`````$1`````のようなプレースホルダー形式を受け入れます。
SQL文をパラメータを含む文字列として組み立てるために、`````fmt`````パッケージの関数を使用したくなるかもしれません – このように:
``````bash
// SECURITY RISK!
rows, err := db.Query(fmt.Sprintf("SELECT * FROM user WHERE id = %s", id))
`
これは安全ではありません!これを行うと、Goは全体のSQL文を組み立て、%s
フォーマット動詞をパラメータ値で置き換えた後、完全な文をDBMSに送信します。これは、呼び出し元がid
引数として予期しないSQLスニペットを送信する可能性があるため、SQLインジェクションリスクを引き起こします。そのスニペットは、アプリケーションにとって危険な予測不可能な方法でSQL文を完成させる可能性があります。
たとえば、特定の%s
値を渡すことで、次のような結果になる可能性があり、データベース内のすべてのユーザーレコードを返すことができます:
SELECT * FROM user WHERE id = 1 OR 1=1;