ナレッジNEW
SQLインジェクションへの対策。主な攻撃の種類と被害例を紹介

この記事では、SQLインジェクションとは何かをはじめ、SQLインジェクション攻撃のリスクと効果的な対策を解説します。プレースホルダやエスケープ処理など具体的な方法も紹介します。
SQLインジェクションとは?
SQLインジェクションとは、攻撃者が悪意のあるリクエストをwebアプリケーションに送信することでデータベース(DB)を不正に利用する(操作する)攻撃手法の一つです。攻撃手段として、DBを操作するためのSQLクエリに対して悪意のあるコードを挿入(Injection)します。

この攻撃は、攻撃対象となるアプリケーションが、ユーザーからの入力を適切に検証することなくSQLクエリに組み込む場合に発生する手法です。国内では2000年代半ばごろ、この攻撃による被害の報道などで騒がれたことから、一定の対策が進みました。
ただし、2020年代になってもしばしば被害が発生する攻撃手法でもあり、過去の攻撃手法とは言い切れません。本記事では、この「SQLインジェクション」と呼ばれる攻撃手法について解説します。
SQLインジェクションはどのような攻撃手法なのか
webシステムを含むシステム全般において、DBには「定義されたデータ」が格納されています。ここではあえて定義されたデータという言葉を使用しましたが、この「定義された」という部分が非常に重要です。この定義の部分に格納された情報の意味や位置付けの情報が付与されているからです。つまり、DBとそこに格納されている情報は、それだけで価値のある情報だと言えるのです。
各種サーバーなどにおけるストレージやメモリ領域に数多くのデータが格納されていますが、それらのデータは、実は定義されていないことが意外と多いのです。ファイルサーバーなどに格納されているデータがそれに該当します。それらのデータは改変の途中であったり、そもそも内容が間違っていることも少なくありません。皆さんも過去に作成した資料の断片のようなものがファイルサーバーに置きっぱなしになっているという状況を見知っていることも少なくないと思います。当然、そのような管理されていないデータには、価値が無いものが混在しているでしょう。
その点、DBにあるデータは、格納される時点で定義された情報であり、重要な情報である確率が高いでしょう。
SQLインジェクションという攻撃が成立する理由
SQLインジェクションという攻撃が成立する理由は、一言で言うとwebアプリケーションの作り方に問題があるためです。言い換えると「SQLインジェクションへの考慮がされていないシステムが持つ脆弱性」となり、この表現の方が分かりやすいかもしれません。
この脆弱性は、ユーザーによる入力をDBへの問い合わせの一部として使用するアプリケーションなどにおいて、 入力された値のチェックやSQL文のメタ文字(特殊な意味を持つ文字)のエスケープ(メタ文字として処理されないような文字列に置換する)設定を行っていなかったり、 それらが不十分であったりすると発生します。
このような場合、 DBに問い合わせる命令文(SQL文)の中に、不適切な文字列を含む入力を与えると、 DBを利用しているプログラムに不正な動作をさせることができてしまいます。
つまり、先述したようなSQLインジェクションという攻撃手法への対策をしていないシステムは、攻撃者によって意図しない動作をしてしまうのです。

SQLインジェクションの主な種類(手段)と被害例
SQLインジェクションによる攻撃があり、その攻撃が成功してしまった場合、以下のような被害が発生する可能性があります。
なお、この攻撃はシステムの中枢に近いDBへの侵入を前提としています。DBには、高い権限を持つID/パスワードなどの重要な情報が格納されることも少なくないため、甚大な被害をもたらす可能性が高い攻撃手法だと言えます。
この攻撃の主な被害の例を以下に記します。
認証の回避
ログイン機能などの認証処理の部分にSQLインジェクションの脆弱性があった場合、本来必要な認証を回避できてしまう可能性があります。この場合、攻撃者が自由にシステム内部に入ることが可能になるため、DBはもちろんシステム全体へ被害が及ぶこともあります。
DBの情報漏えい・改ざんなど
DBに格納されているデータへの参照、更新、削除などの権限が実行可能になります。攻撃者がその権限を実行することにより、DBの情報漏えい、改ざんという形での被害が発生します。
ストアドプロシージャ等を利用したOSコマンドの実行
DB接続ユーザーの権限が高かった場合、サーバーで任意のOSコマンドを実行される可能性があります。これにより、システムの乗っ取りやよそへの攻撃の踏み台として悪用される危険性が発生します。
SQLインジェクションに関する事件
国内での具体的な被害としては、2011年の某家電メーカーが運営するオンラインサービスから1億件を超える個人情報が漏えいした可能性のある事件が最も有名です。その他にも数十~数百万件の情報漏えい事件が定期的に報道されます。
これらの事例を見ると、SQLインジェクションは個人情報を目的としたものだと感じる方が少なくないでしょう。
ただし、日本のIT業界におけるセキュリティ対応は個人情報保護法の施行により事実上、始まったということと、報道も個人情報の漏えい件数にフォーカスする傾向が高かったため、そのように感じやすいという考え方もできます。先述した通り、SQLインジェクションはDBというシステムの中核に近い部分への攻撃になるため、機密情報の漏えい、さらに大きな攻撃の踏み台となる事実も無視できないでしょう。
SQLインジェクションへの対策
SQLインジェクションへの対策は、攻撃候補となるwebサイトがSQLの脆弱性を考慮した作りになっているかどうかという点が重要です。具体的な対策はいくつもありますが、以下にSQLインジェクションへの根本的な対策を紹介します。
[対策①]プレースホルダ(バインド機構)を用いたSQL文の組み立て
SQLインジェクションの対策でまず行うのは、プレースホルダを使ってSQL文を組み立てることです。このプレースホルダをバインド機構として説明している資料も多いですが、どちらも同じことを指しています。
プレースホルダとは、パラメータ部分を別の記号で示しておいて、後で実際の値を機械的な処理で割り当てる(バインドする)手法です。パラメータをこのプレースホルダで指定し入力された値は「文字列」とシステムに判断され、攻撃者の意図を妨げます。
[対策②]入力に対するエスケープ処理を適切に行う
エスケープ処理は、ユーザーからの入力を安全にDBに渡すための方法です。特別な意味を持つ記号の文字(例えば、シングルクォートやダブルクォート)を無害な形式に変換します。
システムにこのような設定をしておくことで、SQLインジェクションを防ぐための手立てとなります。
それ以外の対策
このような根本的な対策以外にも、保険的な対策もあります。
一つは、エラーメッセージをそのままブラウザに表示しないことです。これは、エラーメッセージの内容を攻撃者が悪用することを防ぐ対策と言えます。エラーメッセージには、攻撃の手がかりを与えるだけでなく、実際攻撃された結果を確認する情報源として悪用される場合があるからです。
もう一つの保険的対策は、DBアカウントに適切な権限(最低限の権限)しか付与しないことです。この対策がなぜ有効かというと、DBに接続する際に使用する権限が大き過ぎると、攻撃による被害が拡大し、深刻化する恐れがあるからです。
具体的には、webアプリケーションからDBへ渡す命令文を洗い出し、その命令文の実行に必要な最低限の権限に抑えます。これにより、被害が発生した場合のリスク軽減に役立ちます。
これらの対策は、SQLインジェクションの根本的な対策になるわけではありませんが、保険的な対策として実施することにより、一定の効果があります。
SQLインジェクション対策で大切なこと
SQLインジェクションによる攻撃は、システム設計や実装における脆弱性によって引き起こされます。この脆弱性があると、DBを不正に利用され、認証の回避や情報漏えい、改ざんが発生する可能性があります。
これを防止するためには、SQLを利用しているアプリケーションの場合、その開発者が先述の「プレースホルダ(バインド機構)を用いたSQL文の組み立て」「入力に対するエスケープ処理を適切に行う」といった対策を徹底することに尽きると言っていいでしょう。
なお、これら脆弱性はかなり古くから知られており、対策が進んでいるはずなのですが、対策が確立されてからも定期的に、SQLインジェクションの被害が報道されます。これは、システムの中枢に近いDBが「攻撃者にとって有用なターゲット」であり続けていることを示唆していると考えられます。
そのため、先述した根本的な対策を徹底し、セキュリティ診断(脆弱性診断)などで、このような脆弱性が無いかを第三者が定期的に検査を行い、そのシステムのセキュリティが保たれていることを確認し続けることが必要なのです。
■関連サービス■
この記事は面白かったですか?
今後の改善の参考にさせていただきます!