1. ホーム
  2. sql

[解決済み] パラメータ化されたSQLクエリを作成するにはどうすればよいですか?なぜそうする必要があるのでしょうか?

2023-02-06 21:57:57

質問

すべてのユーザー入力を検証することなく SQL インジェクション攻撃から保護するために、誰もがパラメータ化された SQL クエリを使用していると聞いています。

これはどのように行うのですか? ストアドプロシージャを使用すると、自動的にそうなるのでしょうか?

私の理解では、これはパラメータ化されていないのですね。

cmdText = String.Format("SELECT foo FROM bar WHERE baz = '{0}'", fuz)

これはパラメータ化されるのでしょうか?

cmdText = String.Format("EXEC foo_from_baz '{0}'", fuz)

それとも、SQLインジェクションから身を守るために、このようなもっと大規模なことをする必要があるのでしょうか?

With command
    .Parameters.Count = 1
    .Parameters.Item(0).ParameterName = "@baz"
    .Parameters.Item(0).Value = fuz
End With

パラメータ化されたクエリを使用する利点は、セキュリティの考慮事項の他にありますか?

更新:この素晴らしい記事は、Grotokによって参照された質問のうちの1つにリンクされていました。 http://www.sommarskog.se/dynamic_sql.html

どのように解決するのですか?

この EXEC の例では ではない はパラメータ化されています。このような入力が損害を与えるのを防ぐために、パラメータ化されたクエリ(ある業界ではプリペアドステートメント)が必要なのです。

';DROP TABLE bar;--。

の中に入れてみてください。 fuz 変数に書いてみてください。 bar テーブルを重視するならば、そうしないこともできます)。より微妙で有害なクエリも可能です。

Sql Serverでどのようにパラメータを行うかの例です。

Public Function GetBarFooByBaz(ByVal Baz As String) As String
    Dim sql As String = "SELECT foo FROM bar WHERE baz= @Baz"

    Using cn As New SqlConnection("Your connection string here"), _
        cmd As New SqlCommand(sql, cn)

        cmd.Parameters.Add("@Baz", SqlDbType.VarChar, 50).Value = Baz
        Return cmd.ExecuteScalar().ToString()
    End Using
End Function

ストアドプロシージャはSQLインジェクションの防止に役立つとされることがあります。 しかし、ほとんどの場合、クエリパラメータを使って呼び出す必要があり、そうでなければ役に立ちません。ストアドプロシージャを使用する場合 だけ を使用する場合、アプリケーションユーザーアカウントのSELECT、UPDATE、ALTER、CREATE、DELETEなど(EXEC以外のほぼすべて)のパーミッションをオフにし、その方法でいくつかの保護を得ることができます。