SQLインジェクション攻撃とは何ですか?
ユーザー入力がどのようにSQL命令になるのですか?
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
Webサイトがユーザー入力をSQL文にそのまま付けると、ユーザーはデータではなくSQL文法を入れることができる。 この脆弱性をSQL Injection(SQLインジェクション)と呼びます。
通常話すSQL攻撃はSQLインジェクションを意味することが多い。 正確に言うと、SQLを使用するシステムに対する攻撃はより広い表現であり、そのうち代表的な入力値攻撃がSQLインジェクションである。
文字列をそのまま合わせると生じる問題
ログインコードを次のように作成したとしましょう。
const sql =
"SELECT * FROM users WHERE name = '" + userName +
"' AND password = '" + password + "'";
正常な入力が入ると以下のようなSQLが作られる。
SELECT * FROM users
WHERE name = 'rose' AND password = '1234';
しかし、ユーザー入力に引用符とSQL演算子が入ると、開発者が意図した文の構造が変わることがある。
' OR 1=1 --
SELECT * FROM users
WHERE name = '' OR 1=1 -- ' AND password = '';
1=1は常に真であり、--背面はコメントとして扱うことができます。 データとしてのみ扱わなければならない文字列がSQL命令の一部になってしまったのだ。
どんな被害が起こるのか?
SQLインジェクションが可能であっても、必ずしも同じダメージが発生するわけではありません。 実行中のデータベースの種類、アカウント権限、一度に実行できる文の範囲によって結果が異なります。
それでも一般的に次のような問題が発生する可能性があります。
- ログインチェックをバイパスする。
- 他のユーザーの個人情報を読む。
- 投稿やアカウント情報を変更または削除する。
- エラーメッセージを使用してデータベース構造を調べます。
- データベースアカウントの権限が大きすぎると、ダメージの範囲が広がります。
フロントエンド検査だけでは止められない
ブラウザで引用符の入力を妨げたので、安全だと考えることができる。 しかし、攻撃者はブラウザ画面を経由せずにサーバーにHTTPリクエストを直接送信する可能性があります。
したがって、入力長制限と画面チェックは使いやすさのための補助手段にすぎません。 実際の防御は、SQLを実行しているサーバーで行う必要があります。
SQLインジェクションの主な原因は特殊文字ではありません。 ユーザーデータとSQL命令を文字列一つに混ぜることが根本的な問題だ。