学習のアウトプット【セキュリティについて】
【脆弱性】
アプリケーションなどで、弱点となる部分。
脆弱性をついて、様々な方法で攻撃をされるため、対策としてのセキュリティが必要。
・JavaScriptによる攻撃
・セッションによる攻撃
・不正リクエストによる攻撃
・SQLによる攻撃
について学んだものをまとめた。
---------------------------------------------------------------------------------
【XSS】
JavaScriptはクライアントサイドで動くので、何らかの方法で悪意のあるJavaScriptをインストールさせるなどで、ユーザーが意図しないイベント発火を起こされたりする。
WEBアプリケーションの脆弱性をついて、悪意のあるJavaScriptを実行させるような攻撃をXSS(クロスサイトスクリプティング)と呼ぶ。
ユーザーが開いたHTMLに、何らかの方法でJavaScriptのコードを埋め込む
→意図しないポップアップを発生させたりする攻撃のこと
(スクリプティング=JavaScriptを埋め込んで実行させること)
実際には、個人情報を抜いて別のサーバーに送るようなスクリプティングが多く、脆弱性をつく攻撃はこのXSSが最も多いらしい。
---------------------------------------------------------------------------------
【XSSの流れ(反射型)】
メールやリンク誘導などで、脆弱性のあるWEBアプリケーションのURLをユーザーへ展開
→ユーザーがURLをクリックしてレスポンスが行われると同時に、悪意のあるJavaScriptによりイベントが発火する。
上記の流れを反射型と呼び、別のサイトやメールを介してJavaScriptの誘発を図る点がクロスサイトと表現される所以とのこと。
---------------------------------------------------------------------------------
【XSSの流れ(格納型)】
悪意のあるユーザーが、脆弱性のあるサイトに対して、フォームから悪意のあるJavaScriptを付帯したコンテンツを投稿する
→スクリプトを含んだサイトを開くことでイベント発火する。または、画像などの上にカーソルを乗せることで発火させることもある。
上記のように、脆弱性のあるWEBアプリケーションなどに悪意のあるJavaScriptを埋め込んでおくことを格納型と呼ぶ。
---------------------------------------------------------------------------------
【XSSの要因と対処】
要因→フォームから<script>...</script>とスクリプトタグを入力すると、それがそのままスクリプトとして反映されてしまうため。
対処→文字参照を用いる
---------------------------------------------------------------------------------
【文字参照】
HTMLで使用する記号(タグのための三角カッコなど)は、HTMLのタグなどとして扱われるため、通常であれば文字列として認識させられない。
これらの特殊文字を文字列として認識させるために文字参照が用いられる。
下記の文字を文字参照に変換して表示することで、XSSを防ぐことができる。
変換前 | 変換後 |
---|---|
< | & lt; |
> | & gt; |
& | & amp; |
" | & quot; |
' | & #39; |
---------------------------------------------------------------------------------
【Ruby on RailsにおけるXSS対処】
Railsでは、ヘルパーメソッドによってXSSの対処がされている。
(<%= %>の部分)
仮にフォームで<script>alert("不正なスクリプト")</script>と送付したとしても、そのまま文字列で表示される。
非同期通信で送った場合は、最初は文字列として表示されないが、リロードすると同様に文字列として表示される。
---------------------------------------------------------------------------------
セッションが保存されているクッキーを狙った攻撃。
XSSなどで、非正規ユーザーが正規ユーザーのセッションを盗むこと。
セッションのデータはクッキーでセッションIDという識別番号を用いて保存されるので、このセッションIDが盗まれるとセッションハイジャックとなる。
---------------------------------------------------------------------------------
【セッションID】
正規ユーザー1人1人に与えられる、ユーザーを識別するための番号。
この中にはログインIDや支払い情報、メールアドレスの情報などが含まれるため、
盗まれると
・個人情報閲覧
・不正な決済や送金
・なりすましメールの送信
・SNSへの犯罪予告
などの被害にあうリスクが高まる。
セッションIDへの攻撃方法は、
・セッションIDの推測
・セッションIDの盗み出し
・セッションIDの強制
といったものが挙げられる。
---------------------------------------------------------------------------------
【各セッションハイジャックへの対策】
・セッションの推測
セッションIDを外部情報(メールアドレスなど)から推測してハイジャックを試みるので、セッションIDを自分で作成しないようにすれば良い。
→Ruby on Railsなどのフレームワーク(WEBアプリ開発用のツール)を使えば、セッションIDは自動で生成してくれるので対策となる。
・セッションの盗み出し
基本的にはXSSによってクッキー情報が取得されるので、XSSへの対策を行えばOK。(Document.cookieでクッキー情報が閲覧できる)
また、クッキーなどの個人情報を含んだ通信の際には、通信方式としてSSL通信(暗号化された通信)を用いたサービスを利用することも重要。
http://から始まるサイトはSSL通信に対応しているが、サーバーを独自で準備してサービスを作成する場合などは自身で対策が必要。
※SSL=Secure Socket Layer
・セッションの強制
悪意のあるユーザーが、通常利用者としてセッションIDを取得し、そのIDを含んだリンクを他のユーザーに送付してサービス利用させる
→後からそのセッションIDを使ってハイジャックするという流れ。
ログイン後にセッションIDが自動で変更となる仕様にしておけばよく、deviseを使ったユーザー管理機能であればあらかじめ実装されている。
---------------------------------------------------------------------------------
「サイトをまたいだリクエストの偽造」という意味。
※「クロス」は「cross(交差)」のことで、XSSのクロスと同じ意味。
XSSのクロスがCでなくXなのは、CSSと紛らわしいから。(以前はCSSという名称だったが変更された)
悪意のある第三者が、ユーザー情報を不正取得するサイトを作成し、ユーザーに展開。
ユーザーが、ターゲットとなるアプリケーションにログインした状態でそのサイトを訪れると、ログイン情報を盗み出しセッションハイジャックが成立する。
その後、悪意のあるユーザーがなりすましてターゲットアプリケーションにログインして不正なリクエストを行うという流れ。
XSS:ユーザーのクライアント側の脆弱性をついた攻撃で、WEBアプリケーションがユーザーに表示するデータについて対策が必要
CSRF:サーバー側の脆弱性をついた攻撃であり、サーバー側で受け取るリクエストへの対策が必要
【対策】
決済確定時・ユーザー情報更新時などの重要なタイミングのリクエストに対して
・パスワードなどの再確認
・トークン(一度だけ使用可能なパスワード)の活用
といった対策を行うことが有用。
※Ruby on Railsのヘルパーメソッドも同様にトークンが活用されている。
paramsの中にログイン情報と照合されたトークンを入れ込んでいて、
不正なリクエストかどうか判別ができるようにしている。
注意する点として、トークンが存在するのはPOST・DELETE・PACTH・PUTなどのHTTPメソッドだけなので、createアクションをGETで作成したりしてはいけない。
また、XSSの対策が出来ていなければトークンも抜き出されてしまうので、
総合的な対策が必要である。
---------------------------------------------------------------------------------
投稿フォームなどからSQL文を送って、データベースへの不正アクセス(抜き出しや改ざん)を行う攻撃。
SELECT * FROM users WHERE user_id='$uid' AND password='$pwd'
となっているSQL文に対する攻撃。SQLが「'」で終わることを利用して、パスワードに「' or 'A' = 'A」と入れてフォーム送信すると、パスが通ってしまう(A=Aは常にtrueのため)
対策は・・・
「'」を特殊文字として変換して読み込む一方で、ユーザーから投稿された「'」は単なる文字列として認識して差別化を図る。
②SQL文自体を不正アクセスされにくく記述する(これを「厳格にする」と表現する)
SELECT * FROM users WHERE user_id=? AND password=?
?(プレースホルダー)を用いることで、構文自体を確定したものにしてしまう
→同様にパスワードに「' or 'A' = 'A」と入れても、単純にパスワード不一致で弾かれる。
【プレースホルダー】
仮の引数のようなもので、文章だけを確定させて、入力する値を可変のものにする時に活用する。
【Railsにおける対策】
Ruby on Railsでは、ActiveRecordメソッドを使う場合SQLインジェクションのリスクはほぼない。