GoPostgresqlでSQLインジェクションを防ぐ

Oct 02 2020

Goでのpostgresqlインジェクションのフォーラムを調べたところ、以下のようなSQLインジェクションで役立つ情報がいくつか見つかりました。

Golangを使用してSQLでINルックアップを実行するにはどうすればよいですか?

「データベース/ SQL」の使用中にGoでSQLインジェクション攻撃を防ぐにはどうすればよいですか?

しかし、Goのコードは別の種類のコードとユースケースを使用しているため、まだアドバイスが必要です。私がアドバイスを必要とするいくつかのユースケース/質問はこのようなものです

  1. INSERT INTO a (a1,a2,a3) VALUES (%d,%d,%s)fmt.Sprintfを使用するように、複数の挿入にクエリループを使用すると、sprinftを使用するのは悪いことです。それで、挿入のためのこのループクエリの解決策はありますか?例:INSERT INTO a (a1,a2,a3) VALUES (%d,%d,%s),(%d,%d,%s),(%d,%d,%s)
  2. paramが%d代わりにを使用している場合、fmt.Sprintfを使用してクエリを生成するのは安全%sですか?
  3. プリペアドステートメントとクエリの使用は安全ですが、関数Selectを使用している場合はどうなりますか( $1,$2)および関数NamedQuery(名前付き構造体を使用)例:Select * from a where text = $1->この$1セーフを使用していますか?例:Select * from a where text = :text->これは関数NamedQueryで安全ですか?

親切にあなたのアドバイスを必要としています。ありがとうございました!

回答

5 KennyGrant Oct 02 2020 at 18:20

まず、通常、dbプレースホルダーを使用することを好みますか?$ 1など

  1. はい、整数パラメーターでfmt.Sprintfを使用してSQLを構築するのは安全ですが、可能であれば回避する価値がありますが、3番目のパラメーターは%sです-それを回避して?
  2. はい、整数パラメーターでfmt.Sprintfを使用するのは安全ですが、%sまたは%vははるかにリスクが高く、避ける必要があります。なぜそれが必要なのか考えられません。
  3. ここでプレースホルダーを使用してください。そうすれば安全です。

一般的なルール:

  • デフォルトでプレースホルダーを使用します。%dを使用することはめったにありません(たとえば、INクエリのように)
  • 検証または使用する前に、パラメータを整数などの型に解析します
  • 可能であれば文字列の連結を避け、特に文字列パラメータに注意してください
  • 列名やテーブル名などは常にハードコーディングし、ユーザー入力から生成しないでください(例:?sort = mystringcolname)
  • 取得するパラメータがそのユーザーに対して許可されているもののみであることを常に検証してください