SQLインジェクションについての質問に出くわしたとき、同僚と私はSOを閲覧していましたが、パラメータ化されたクエリは内部でどのように機能するのでしょうか。使用しているAPI(パラメーター化されたクエリをサポートしていると仮定)は、クエリとパラメーターを組み合わせて連結を実行しますか?または、パラメーターはクエリとは別にSQLエンジンに到達し、連結はまったく実行されませんか?
グーグルはあまり役に立たなかったが、おそらく私たちは正しいものを探していなかった。
SQLインジェクションについての質問に出くわしたとき、同僚と私はSOを閲覧していましたが、パラメータ化されたクエリは内部でどのように機能するのでしょうか。使用しているAPI(パラメーター化されたクエリをサポートしていると仮定)は、クエリとパラメーターを組み合わせて連結を実行しますか?または、パラメーターはクエリとは別にSQLエンジンに到達し、連結はまったく実行されませんか?
グーグルはあまり役に立たなかったが、おそらく私たちは正しいものを探していなかった。
パラメータは、クエリとは別にSQLエンジンに到達します。パラメータ化されたクエリに対して計算または再利用された実行プラン。クエリは、パラメータを使用してSQLエンジンによって実行されます。
パラメータはそのままSQLサーバーに到達し、入力または出力などのタイプを示すメタデータで個別に「パッケージ化」されます。AlexReitbortが指摘するように、パラメータ化されたステートメントはサーバーレベルの概念であり、単なる便利なものではないためです。さまざまな接続レイヤーからコマンドを呼び出す方法。
SQL SERVERが、パラメータリストが連結されている特定のパラメータ化されたクエリから完全なクエリ文字列を構築することは疑わしいです。
ほとんどの場合、指定されたパラメータ化されたコマンド文字列を解析して、予約語と記号(SELECT、FROM、 "、"、 "+"など)に基づいて内部データ構造に分割します。そのデータ構造内には、テーブル名、リテラルなどの値のプロパティ/場所があります。ここで、(リストから)渡された各パラメーターをその構造の適切なセクションにコピー(逐語的)します。
したがって、@ UserNameの値は次のようになります:'x';ユーザーから削除-
inをエスケープする必要はなく、実際のリテラル値として使用するだけです。
パラメータは(クエリ内ではなく)クエリとともに渡され、基になるデータベース通信プロトコルに従って送信されるため、APIによって自動的にエスケープされます。
たとえば、
Query: <<<<select * from users where username = :username>>>>
Param: <<<<:username text<<<<' or '1' = '1>>>>>>>>
これは、データベースプロトコルが実際に使用する正確なエンコーディングではありませんが、理解できます。