【Rails:8】セキュリティとAjax

セキュリティ

  • SQLインジェクション
    WEBアプリケーションに対して、不正にデータを操作したり、任意のSQL文を実行させてしまうような攻撃。
    • 危険な式
      次のように、変数を直接SQL文に埋め込むコードは危険です。
# params[:owner_name] = "hoge" のとき
  Mail.find(:all, :conditions => "owner_name = '#{params[:owner_name]}'")
  #=> select * from mails where owner_name = 'hoge'; (ユーザhogeのメールをすべて取得)

# params[:owner_name] = "' OR 1 --'" のとき
  Mail.find(:all,
            :conditions => "owner_name = '#{params[:owner_name]}'")
  #=> select * from mails where owner_name = '' OR 1 --''; (すべてのメールを取得)
                                            # OR 1 は常に真
                                            # -- 以降は無視される
    • 安全な式
      バインド変数を使用すると、変数の値は自動的にクォートされます。
# params[:owner_name] = "' OR 1 --'" のとき
  Mail.find(:all,
            :conditions => ["owner_name = ?", params[:owner_name]])
  Mail.find(:all,
            :conditions => ["owner_name = :name", :name => params[:owner_name]])
  #=> select * from mails where owner_name = '''' OR 1 --'''';
  #   ' OR 1 --'のシングルクォーテーションがエスケープされ、さらに文字列全体も''で囲まれる
  • クロスサイトスクリプティングXSS
    他ユーザの情報を不正に入手するため、JavaScript等を使ってcookieを盗む攻撃。
    • メタ文字のエスケープ
      レンダリングする文字列の中に含まれるメタ文字( < や > )を &lt; や &gt; にエスケープしてやれば、危険なコードが実行される恐れはありません。
      • h() / html_escape()::メタ文字をすべてエスケープ
      • sanitize()::一般的なHTMLタグはそのままで、危険性の高いメタ文字のみエスケープ
パス・トラバーサル 開発者の意図に反して、他のディレクトリパスやファイルにアクセスする攻撃
【対策】パスワードが書いてあるファイルなど、アクセスされては困るファイルを /public 以下に置かない
オーバーフロー コンピュータが数値演算を行なった結果が、扱える数値の最大値を超えること
【対策】すべての入力フォームに文字制限やサイズ制限をかける
OSコマンドインジェクション 悪意あるリクエストにより、Webサーバ側で意図しないOSコマンドを実行させる攻撃
【対策】Rubyでシェルが実行できるShell classのメソッド等を使う場合、引数等で特殊な文字を無効化する
パスワード推測 パスワード・ファイルを不正入手し、保存されているハッシュと一致するパスワードを推測する攻撃
【対策】パスワード入力画面で、パスワードを推測しやすい入力形式やエラーメッセージを含まないようにする
表記の改ざん WEBページをローカルで編集し、ブラウザからの入力データを改ざんする攻撃
【対策】type="hidden" 等で編集されては困る値を入れない(入れる場合チェックをかける)
セッションハイジャック 何らかの方法で他ユーザのセッションIDを入手し、そのユーザ専用のページにアクセス等する攻撃
【対策】携帯用アプリであれば、適切なところでURLのセッションと携帯の個体識別番号を照合する
ネットワーク盗聴 ネットワーク上を流れている暗号化されていないパケットを読み取る攻撃
【対策】適切なところでSSL通信を行う
フィッシング詐欺 本物のWEBサイト・企業等を装い、偽のウェブサイトへ誘導するなどして、個人情報を盗み出す攻撃
【対策】適切なところで電子証明書を表示する
盗み見 【対策】重要な情報の入力を求めるとき、"*" 等で隠す
バックドアデバッグオプション バックドア::開発者が不正に作り込んだ裏口
デバッグオプション::開発時のデバッグ用のコードがそのまま残っているもの
【対策】バックドア・デバックオプションを残さない
Client Side Comment
(クライアント側コメント)
HTMLファイルのコメント部分
【対策】表示されるソースのコメント部分に機密情報を残さない
CSRF
(Cross Site Request Forgeries)
WebサイトにスクリプトやHTTPリダイレクトを仕込むことによって、閲覧者に意図せず別のWebサイト上での操作を行なわせる攻撃
【対策】サイト外からのリクエストの受信を適切に拒否する

Ajax

  • Ajax(Asynchronous JavaScript and XML
    従来のWEBアプリケーションでは、サーバはリクエストごとに新しくHTMLを返します。
    しかしAjaxを利用すれば、サーバはHTMLフラグメント(JavaScript・データ等)を送り返し、WEBページの一部のみレンダリングすることができます。
    • XMLHttpRequest
      Ajaxで使われるJavaScriptオブジェクト。
      このオブジェクトは、サーバへのHTTP呼び出しを生成したり、返されたデータを処理することができます。
      ブラウザ側では、ユーザの通常のリクエストとはまた別に、XMLHttpRequestによるリクエストを受け付けています。
<%= javascript_include_tag "prototype" %>
    • テンプレートからAjax呼び出し
<%= link_to_remote("Ajax実行",                                  <!-- リンクを貼る文字列 -->
                   :update => 'my_ajax',                        <!-- Ajax適用部分のdiv属性名 -->
                   :url => {:action => 'action_for_ajax'}) %>   <!-- アクションの指定 -->
<div id="my_ajax">ここにAjaxが適用されます</div>
def action_for_ajax
  …
  render(:layout => false)
  # テンプレートの一部だけをレンダリングするため、レイアウトは不要
end
    • Ajax用ヘルパー
      • form_remote_tag
        Ajax用のform_tagです。
        ただし、画像アップロードには対応していません。
      • observe_field
        :frequencyオプションで指定した秒数ごとに、アクションを実行します。
      • periodically_call_remote
        :frequencyオプションで指定した秒数ごとにサーバを呼び出し、更新します。