Programmingウェブ/アプリケーション開発者

動的に生成されたSQLクエリの安全な実行アプローチを説明してください。SQLのプログラミングと外部パラメータの扱いでSQLインジェクションからどのように保護しますか?

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

回答

最も信頼性の高い方法は、常にパラメータ化クエリまたは準備されたステートメントを使用し、ユーザーの値との単純な文字列連結でクエリを生成しないことです。

より複雑なシナリオ(手続き内の動的SQL)には、特別なエスケープメカニズムやホワイトリスト(パラメータの厳格なフィルタリング)を適用してください。

例:

  • アプリケーションレベル(Python, Java, C#):
cursor.execute('SELECT * FROM users WHERE login = %s', [login])
  • SQL内部(PostgreSQL):
EXECUTE format('SELECT * FROM %I WHERE id = $1', tablename) USING id;

ここで、%Iは安全な方法でテーブル名/カラム名だけを挿入します。

トリックの質問

次の数値を文字列に挿入するアプローチは安全ですか?

EXECUTE 'SELECT * FROM users WHERE id = ' || user_input;

いいえ! 数値を期待していても、悪意のあるユーザーがコードを渡すことができます: 1; DROP TABLE users; — クエリが実行されてしまいます。したがって、常にプレースホルダと明示的な入力パラメータの型チェックを使用してください。

このトピックの細かい知識不足による実際のエラーの例


ストーリー 1

従業員検索フォームは、アプリケーション側で文字列の連結を通じてWHERE条件を構築していました。悪意のあるユーザーは: ' OR 1=1 -- を入力し、すべての従業員のデータが表示されました。後に同様のアプローチでデータセクションが削除されました。結論: 重要なパラメータの連結は常にリスクがあります。


ストーリー 2

管理インターフェースでレポートを選択する際、テーブル名がユーザーフィールドから引き出され、SQLクエリに挿入されました。ユーザーは無効な名前を挿入し、システムテーブルへのアクセスを得ることができました。その後、厳密に定義された名前のみを許可しました(ホワイトリスト)。


ストーリー 3

eコマースプロジェクトで、動的なソート時にユーザーがGETパラメータでフィールド名を渡していました。ハッカーはprice; DELETE FROM orders; --を挿入し、すべての注文を失いました。許可されるカラム名のフィルタリングとパラメータ化されたクエリの使用が問題を解決しました。