Programmingフルスタック開発者

パラメータ化クエリと動的SQLについて説明してください。それぞれのアプローチをいつ使用するか、動的SQLに関連するリスクとそれを回避する方法を教えてください。例を挙げてください。

Hintsage AIアシスタントで面接を突破

回答。

パラメータ化クエリは、値を変数の置き換えではなく、特別なパラメータを通じてクエリに渡すことを可能にします。これにより、セキュリティが向上し、SQLインジェクションから保護され、再利用するクエリの実行がキャッシュプランによって高速化されます。

動的SQLは、クエリをリアルタイムで構築および実行することを可能にします(例えば、MS SQLではEXEC sp_executesqlやPostgreSQLではPREPARE/EXECUTEを通じて)。直接的にクエリ文に値を挿入すると、SQLインジェクション、構文エラー、およびパフォーマンスの低下を引き起こす可能性があるため、十分な注意が必要です。

パラメータ化クエリの例(Pythonでpsycopg2ライブラリを使用):

cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

PostgreSQLにおける動的SQLの例:

EXECUTE format('SELECT * FROM %I WHERE value = %L', tablename, value);

トリックのある質問。

質問: なぜ、一部の古いアプリケーションが行っているように、単に引用符(')をエスケープするだけではSQLインジェクションからの保護として不十分ですか?

回答:

引用符をエスケープすることは、すべてのタイプのインジェクションを防ぐわけではなく、特に攻撃者がSQLクエリの構造を挿入する場合(例えば、"; DROP TABLE users;")には効果がありません。さらに、異なるデータ型のさまざまな特性をカバーしておらず、エンコーディングや特殊文字によるフィルタのバイパスから保護することもできません。常にパラメータ化クエリを使用する必要があります。


歴史

ある給与計算システムでは、動的SQLがレポートを生成していました。古いフレームワークでパラメータ化がサポートされていなかったため、手動で文字列を結合していました。あるユーザーが偶然(またはそうでないか)「姓」フィールドにSQLの一部を挿入したため、他人の給与情報にアクセスできることとなりました。

歴史

ある小規模なオンラインショップは、適切なバリデーションなしに商品フィルタリングに動的SQLを使用していました。非標準の値を指定しようとしたユーザーがSQLパーサーエラーを引き起こし、一時的にすべての商品の出力が「ダウン」しました。

歴史

CRMでは、「O'コンナー」という名前のために、単純な文字列結合でSQLクエリを構築するアプリケーションにエラーが発生しました。エスケープされていないシングルクォーテーションのために、その名前のカードは全く保存されず、これが発見されたのは1年後でした。