SQLインジェクションとはなんぞや

こんにちは!kossyです!



なんぞやシリーズ第二弾ということで、今回はSQLインジェクションについて調べてみました。
引用だらけでキュレーションメディアみたいになってしまったので、
何度も読んで自分の言葉で噛み砕いて説明できるようにする必要性を感じてます、、、


以下、本文です。




そもそもSQLって?

SQLとは、データベースから値を取り出したり、データを挿入したりする指示を出す専用の言語のことです。
SQLはISO(国際標準化機構)なる組織で規格が標準化されており、一度学習すればほかのデータベースでもほぼ同じように操作可能です。

SQLの読み方は、「エスキューエル」や「シークウェル」が一般的だそうです。










SQLインジェクションって?

まずはwikipediaで調べてみました。


SQLインジェクション(英: SQL Injection)とは、アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。 また、その攻撃を可能とする脆弱性のことである。

出典:SQLインジェクション - Wikipedia


うーん?って感じなので別のサイトでも調べてみました。



データベース(DB)と連携して動作するWebサイトでは、外部から入力された値を元にSQL文(データベースへの命令文)を組み立てることがよくあります。SQLインジェクション脆弱性を持つサイトでは、入力された値によっては意図しないSQLが生成され、結果として不正にDBのデータが読み取られたり、データが改ざんまたは削除されたりするなどの被害をこうむる可能性があります。

出典: https://academy.gmocloud.com/advance/20150608/700

なるほど、不正に操作することの具体例がわからなかったから理解が甘くなってたわけですね。


実際にSQLインジェクション攻撃を起こすSQL文も紹介されていました。
SQLインジェクションでデータベースを攻撃(!)してみよう (解答編) | 丸ノ内テックブログ


適切に対策しないと、個人情報が流出してしまうこともあるんですね。









SQLインジェクション対策


先ほど紹介したブログには以下の記述がありました。


SQLインジェクションには決められたパターンがあります。
たとえば、自分が実行したいSQLをちゃんと動作させるために、前後に書かれたSQL文を無効化、もしくは無難に終わらせる必要があります。
そのため、多くの場合はSQLインジェクションを行うための入力値として、最初に「\’」を持って来たり、また後には「;–」と書いて以降のSQLを無効化します。
要は、これらの値が入ってきてしまう可能性があるプログラムの書き方をしていれば、SQLインジェクションが発生してしまうということになります。
こういった理由から、プリペアドステートメントを使うなど、適切なSQLインジェクション対策を行わなければいけないのです。

出典: SQLインジェクションでデータベースを攻撃(!)してみよう (解答編) | 丸ノ内テックブログ


プリペアドステートメントの意味がわからなかったため、調べてみました。

prepareメソッドはプリペアドステートメントと呼ばれるものを利用するための関数です。
プリペアドステートメントとは、SQL文を最初に用意しておいて、その後はクエリ内のパラメータの値だけを変更してクエリを実行できる機能のことです。
この機能を利用することでクエリの解析やコンパイル等にかかる時間は最初の一回だけで良くなり、より高速に実行することができます。
また、SQLインジェクション対策に必要なパラメータのエスケープ処理も自動で行ってくれるため、安全かつ効率の良い開発が出来ます。

出典: PDO prepare プリペアドステートメントの使い方 | PHP入門~bituse~

あらかじめ値をセットしたSQL文を書くのではなくて、
動的に変更できるようにする機能という意味でしょうか。(間違ってたら教えてください、、、)


他のページも閲覧してみました。



3-1:サーバでの対策
 SQLインジェクションは、主にWebアプリケーションのプログラムに問題があります。その問題は、入力した文字列にSQL文を仕込まれた場合に、それを命令文と認識してしまうことです。そのため、SQL文を成り立たせない実装が有効になります。これを「エスケープ処理」といいます。具体的には、SQL文で特別な意味を持つ記号や文字列を、別の文字に置き換えたり削除したりします。
 例えば、入力された文字列の中に「’」(シングルクォート)があった場合には、これを「”」(ダブルクォート)に置き換えます。これにより、ログイン認証を回避する「’or’1’=’1」というコードが「”or”1”=”1」に変換され、無害な普通の文字列として認識されるようになります。また「’」だけでなく「/」(バックスラッシュ)にも、同様の処理を行います。
 言語によっては、バインド機構(SQL文に変数の場所を示す記号を置いた後に実際の数値を割り当てる仕組みのこと)を利用することで、独自にエスケープ処理を行う必要がなくなります。このほか、入力エリアに入力できる文字や文字数などに制限を設けることも有効です。

3-2:ネットワークでの対策
 SQLインジェクションに限らず、脆弱性が公表されたときには、その脆弱性を解消するためのパッチやアップデートが合わせて公開されます。これらをすぐに適用すれば、脆弱性を狙った攻撃から保護することができます。しかし、Webアプリケーションの場合は、ほかに動作している多くのアプリケーションに悪影響を及ぼしてしまう可能性があるため、適用の前に検証が必要になります。
 しかし、検証には時間がかかりますし、検証後すぐに適用することも難しいのが現状です。とはいえ、あまり時間が空いてしまうと、脆弱性を悪用した攻撃が行われる可能性もあります。そこで最近、ニーズが高まっているのが「WAF(Webアプリケーション・ファイアウォール)」です。
 WAFは、Webアプリケーションに送られる通信をチェックするのですが、WAFはさまざまな脆弱性に対する攻撃コードをシグネチャとして持っていて、これと合致するコードを無効化します。つまり、脆弱性を解消するのではなく、その脆弱性を悪用しようとする攻撃を検知して対策を行います。導入や管理・運用が容易なクラウド型のWAFも複数提供されているため、脆弱性対策として導入を検討することも方法のひとつです。

3-3:Webに脆弱性がないか検査する
 SQLインジェクションに限らず、Webアプリケーションの脆弱性は定期的にチェックしたいものです。ベストな対応は、Webサイトで使用しているすべてのソフトウェアやアプリケーションのバージョンを把握し、パッチやアップデートが公開されたら迅速に適用することですが、なかなか難しいのが現状です。
 そこで、外部から擬似的な攻撃を行い、悪用されると危険な脆弱性があるかどうかを確認する「脆弱性診断」というサービスがあります。検査する脆弱性の内容はサービスによって異なりますが、多く使用されているものや、「OWASP Top 10」などに挙げられているものには対応しているケースが多くなっています。別のサービスに付帯しているケースも多いので、調べてみるとよいでしょう。

3-4:それぞれの立場で対策を
3-4-1:開発者
 Webアプリケーションやデータベースの開発者は、SQLインジェクションを引き起こされないようプログラミングする必要があります。最近では、セキュアプログラミングやシフトレフトなどとも呼ばれますが、脆弱性を作り込んでしまわないことが重要です。ガイドライン も複数出ていますので、参考にするとよいでしょう。

IPA:「安全なウェブサイトの作り方」
・OWASP Top 10:「最も重大なウェブアプリケーションリスクトップ10(PDF)」
・JSSEC:「Androidアプリのセキュア設計・セキュアコーディングガイド」
経済産業省:「開発者向けセキュリティ関連コンテンツ」(リンク集)

3-4-2:発注者、社内IT部門など
 Webアプリケーションやデータベースなどを発注する側は、依頼書や仕様書に脆弱性対策があることを確認しましょう。また、IT部門など利用する側は、サーバなどの脆弱性対策の確認、あるいは利用するWebアプリケーションやソフトウェアのバージョン管理、定期的な脆弱性診断などを行います。WAFによる攻撃防御も検討しましょう。

出典: SQLインジェクション攻撃への対策|脆弱性を悪用する仕組みと具体例








RailsでのSQLインジェクション対策

公式ガイドには、


Ruby on Railsには、特殊なSQL文字をフィルタする仕組みがビルトインで備わっています。「'」「"」NULL、改行がエスケープされます。Model.find(id)やModel.find_by_なんちゃら(かんちゃら) に対しては自動的にこの対応策が適用されます。ただし、SQLフラグメント、特に 条件フラグメント (where("..."))、connection.execute()またはModel.find_by_sql()メソッド については手動でエスケープする必要があります。

出典: Rails セキュリティガイド | Rails ガイド

との記述がありました。
具体例は以下のqiita記事が参考になりそうです。
qiita.com