Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20080521-Ruby-on-Rails-Security

2,919 views

Published on

Published in: Technology
  • Be the first to comment

20080521-Ruby-on-Rails-Security

  1. 1. 2008-05-21(水); Apple Store Sapporo Ruby Sapporo Night vol.6 Rails 入門 セキュリティ Ruby on Rails Security 日本Rubyの会島田浩二 Ruby札幌 snoozer.05@ruby-sapporo.orgSHIMADA Koji; Nihon Ruby-no-kai; RubySapporo
  2. 2. Tell The Topic of Ruby, RubySapporo! Ruby札幌、Rubyの話しろ!
  3. 3. しまだこうじhttp://iddy.jp/profile/snoozer05✓ ふつうのフリーランス・プログラマ✓ 日本Rubyの会 ✓ Ruby札幌 運営 ✓ RubyKaigi スタッフ/実行委員✓ プログラミングの楽しさを共有したい✓ 自分の知らないコトやヒトに出会いたい
  4. 4. どうぞ よろしくお願いします
  5. 5. まとめ✓ Railsは標準でさまざまなセキュリ ティ対策をサポートしている✓ 重要なのはRailsによる対策のポイン トを理解すること✓ 用法・用量を守って正しくお使い下 さい
  6. 6. 今日のゴール✓ Railsアプリがセキュアかどうかを 確認するための、いくつかの基本的な チェック項目について知る✓ それぞれのチェック項目を満たすため の作戦を知る
  7. 7. チェックリスト
  8. 8. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  9. 9. 一つずつ
  10. 10. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  11. 11. チェック項目1見せなくてよい情報を 公開していないか
  12. 12. 見せなくてよい情報を公開していないか
  13. 13. 見せなくてよい情報を公開していないか
  14. 14. 見せなくてよい情報を公開していないか
  15. 15. 見せなくてよい情報を公開していないか
  16. 16. 見せなくてよい情報を公開していないか 422ステータスのテンプレートが デフォルトで用意されているのは Rails2.0∼
  17. 17. 何が起きるか✓ 攻撃者に攻撃方法を考えるヒントを 与えてしまう✓ フレームワークや固有のバージョン の脆弱性をつかれる可能性がある
  18. 18. 対策✓ 攻撃のヒントになる可能性のある情報は、極力表に出さない✓ デフォルトのページなどをそのままにしない✓ アクセス制御をきちんと
  19. 19. 対策config/routes.rbActionController::Routing:: Routes.draw do ¦map¦ … map.root :controller => "welcome" …end トップページが指定された場合の ルーティング先を定義
  20. 20. 対策 各種デフォルトのテンプレートを きちんと差し替える
  21. 21. 対策httpd.conf…<DirectoryMatch "^/.*/.svn/"> ErrorDocument 403 /404.html Order allow,deny Deny from all Satisfy All</DirectoryMatch>… Webサーバでファイルのアクセス に関する適切な設定を行う
  22. 22. 見せなくてよい情報を 公開していないか✓ 攻撃のヒントになる可能性のある情報は、極力表に出さない✓ デフォルトのページなどをそのままにしない ✓ ステータスページ等✓ アクセス制御をきちんと ✓ サーバの設定などをきちんと確認
  23. 23. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  24. 24. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  25. 25. チェック項目2重要なモデル属性を 保護できているか
  26. 26. 重要なモデル属性を 保護できているかdb/migrate/00X_create_users.rb create_table :users do ¦t¦ t.string :login t.string :name t.string :password t.integer :admin, :default => 0 endapp/models/user.rb 制御に絡む属性 class Users < ActiveRecord::Base end
  27. 27. 重要なモデル属性を 保護できているかdb/migrate/00X_create_users.rb create_table :users do ¦t¦ t.string :login t.string :name t.string :password t.integer :admin, :default => 0 endapp/models/user.rb 何のガードもしていない 制御に絡む属性 class Users < ActiveRecord::Base end
  28. 28. 重要なモデル属性を 保護できているかhttp://example.com/users/new
  29. 29. 重要なモデル属性を 保護できているかhttp://example.com/users/new
  30. 30. 何が起きるか✓ 攻撃者の視点✓ このフォームを使って何か攻撃できないか✓ フィールドにありそうな属性でも追加 してみるか✓ ユーザ情報だったら管理者権限か✓ とりあえずadminあたりから
  31. 31. 何が起きるかオリジナルのフォーム <form action="/users" method="post"> <input name="user[login]" type="text" /> <input name="user[name]" type="text" /> <input name="user[password]" type="text" /> <input name="commit" type="submit" value="Create" /> </form>
  32. 32. 何が起きるか改変されたフォーム <form action="/users" method="post"> <input name="user[login]" type="text" /> <input name="user[name]" type="text" /> <input name="user[password]" type="text" /> <input name="user[admin]" type="text" /> <input name="commit" type="submit" value="Create" /> </form>
  33. 33. 何が起きるか改変されたフォーム <form action="/users" method="post"> <input name="user[login]" type="text" /> フォームを改変されて使用されると <input name="user[name]" type="text" /> <input name="user[password]" type="text" /> 公開していない属性でも上書きされてしまう <input name="user[admin]" type="text" /> <input name="commit" type="submit" value="Create" /> </form>
  34. 34. 対策✓ 制御に絡む属性はきちんと保護する✓ フォームからのリクエストで直で更新しない✓ ARが提供している仕組みを利用する ✓ attr_protected, attr_accesible
  35. 35. 対策attr_protectedのサンプルclass Users < ActiveRecord::Base attr_protected :adminend 指定した属性は一括代入時には無視されるattr_accesibleのサンプルclass Users < ActiveRecord::Base attr_accesible :login, :name, :passwordend 指定した属性以外は一括代入時には無視される
  36. 36. 重要なモデル属性を 保護できているか✓ 制御に絡む属性はきちんと保護する✓ フォームからのリクエストで直で更新しない✓ ARが提供している仕組みを利用する ✓ attr_protected, attr_accesible ✓ 開発当初はattr_protectedを使用し、開発 が進み制御に絡む属性が増えてきたら attr_accesibleへ切り替えるのが吉
  37. 37. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  38. 38. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  39. 39. チェック項目3コントローラメソッドが公開されていないか
  40. 40. コントローラメソッドが 公開されていないかapp/controllers/users_controller.rbclass UsersController < ApplicationController # 外部に公開しているアクション def activate mark_as_activate if valid_request end # 具体的にアクティベート化を行う処理 def mark_as_activate ... end publicメソッドとして定義してしまっているend
  41. 41. 何が起きるか✓ 内部処理が外部からアクションとして 呼べてしまう✓ ブラウザ等から容易に実行できてしまう✓ 悪意がなくても踏んでしまう危険性が ある✓ 一度でも呼ばれると、システムの整合性 は保証できない
  42. 42. 対策✓ コントローラメソッドのアクセス制 御をきちんと管理する✓ アクションではないメソッドはpublic にしない✓ アクセス制御の明示 ✓ private, protected
  43. 43. 対策app/controllers/users_controller.rbclass UsersController < ApplicationController def activate mark_as_activate if valid_request end private def mark_as_activate ... endend
  44. 44. コントローラメソッドが 公開されていないか✓ コントローラメソッドのアクセス制 御をきちんと管理する✓ アクションではないメソッドはpublic にしない✓ アクセス制御の明示 ✓ private, protected
  45. 45. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  46. 46. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  47. 47. チェック項目4 出力ページの エスケープ処理に 漏れはないか
  48. 48. 出力ページのエスケープ処理に 漏れはないかapp/views/users/show.erb.rhtml...<p> <b>Name:<b> <%= @user.name %></p>... hメソッドによる、特殊文字のHTMLエンティ ティとしてのエスケープ処理が漏れている
  49. 49. 何が起きるか✓ クロスサイト・スクリプティング攻撃(XSS)✓ 攻撃者が埋め込んだ任意のスクリプトが 出力ページ内に挿入されてしまう✓ ページの訪問者のCookie情報が盗み取られ る等、致命的な被害を引き起こす入り口
  50. 50. 対策✓ 出力ページのエスケープ処理について 漏れがないことを確認する✓ SafeERBプラグインを使用しエスケープ 漏れを検出✓ sanitizeメソッドを使用しホワイトリス ト形式で出力時にスクリプトを除去
  51. 51. 対策✓ SafeERB✓ http://agilewebdevelopment.com/plugins/safe_erb✓ taint機構を使ってエスケープ漏れを チェック✓ エスケープ漏れがあると例外 ✓ SQLiteから取り出した値はtaintedではない ので例外が出ないので注意→確認する場合は PostgresやMySQLで
  52. 52. 対策✓ sanitizeメソッド ✓ ホワイトリスト方式を使用し任意のタグ を除去app/views/users/show.erb.rhtml ... <p> <b>Name:<b> <%= sanitaize(@user.name) %> </p> ...
  53. 53. 出力ページのエスケープ処理に 漏れはないか✓ 出力ページのエスケープ処理について 漏れがないことを確認する✓ SafeERBプラグインを使用しエスケープ 漏れを検出✓ sanitizeメソッドを使用しホワイトリス ト形式で出力時にスクリプトを除去
  54. 54. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  55. 55. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  56. 56. チェック項目5 DBへ渡す入力の エスケープ処理に 漏れはないか
  57. 57. DBへ渡す入力のエスケープ処理に 漏れはないかapp/controllers/user_controller.rb
  58. 58. DBへ渡す入力のエスケープ処理に 漏れはないかapp/controllers/user_controller.rb ユーザ入力をそのままSQLへ変換してしまって いるためエスケープ処理が行われていない
  59. 59. DBへ渡す入力のエスケープ処理に 漏れはないかapp/controllers/user_controller.rb ユーザ入力をそのままSQLへ変換してしまって いるためエスケープ処理が行われていない
  60. 60. 何が起きるか✓ SQLインジェクション✓ サーバ上で実行されるSQLを攻撃者が 制御可能になってしまう✓ データベースを不正操作され致命的な被 害を引き起こす
  61. 61. 対策✓ SQLの組み立てにはバインド変数を使 用しSQLのメタ文字をエスケープする✓ ?プレースホルダの使用して値を指定✓ 名前付きバインド変数のハッシュを使用
  62. 62. 対策✓ プレースホルダの使用User.find(:first, :conditions => [ name = ? , params[:name]])User.find(:all, :conditions => [ category IN (?) ,[1, 2, 3]])
  63. 63. 対策✓ 名前付きバインド変数の使用User.find(:first, :name => params[:name], :password => params[:password])User.find(:first, :conditions => [ name = :name , :name => params[:name]])
  64. 64. DBへ渡す入力のエスケープ処理に漏れはないか✓ SQLの組み立てにはバインド変数を使 用しSQLのメタ文字をエスケープする✓ ?プレースホルダの使用して値を指定✓ 名前付きバインド変数のハッシュを使用
  65. 65. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  66. 66. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  67. 67. チェック項目7 外部ページからの不正なリクエストをガードできているか
  68. 68. 外部からの不正なリクエストを ガードできているかapp/views/blog/edit.rhtml<% form_for(@blog) do ¦f¦ %> ...<% end %>app/controllers/blogs_controller.rbclass BlogsController < ApplicationController ... def update ... リクエスト処理に対して end 何もガードをかけていない ...end
  69. 69. 何が起きるか✓ クロスサイトリクエストフォージ(CSRF)✓ 攻撃者の誘導により、ユーザが外部ペー ジから攻撃者の用意したリクエストを 実行してしまう
  70. 70. 対策✓ リクエストの有効性を検証する✓ Rails2.0からはデフォルトで対策の処理 が入っている✓ protect_from_forgery ✓ ApplicationControllerクラスで指定 ✓ Railsの生成するフォームと対で検証用 のトークンを持ち、それらを比較するこ とでリクエストの有効性を評価
  71. 71. 対策✓ protect_from_forgeryの使用class ApplicationController < ActionController::Base protect_from_forgeryendclass BlogController < ApplicationController::Base protect_from_forgery :only => [:create,:update]end
  72. 72. 外部からの不正なリクエストを ガードできているか✓ リクエストの有効性を検証する✓ Rails2.0からはデフォルトで対策の処理 が入っている✓ protect_from_forgery ✓ ApplicationControllerクラスで指定 ✓ Railsの生成するフォームと対で検証用 のトークンを持ち、それらを比較するこ とでリクエストの有効性を評価
  73. 73. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  74. 74. チェックリスト1. 見せなくてよい情報を公開していないか2. 重要なモデル属性を保護できているか3. コントローラメソッドが公開されていないか4. 出力ページのエスケープ処理に漏れはないか5. DBへ渡す入力のエスケープ処理に漏れはないか6. 外部ページからの不正なリクエストをガードできているか
  75. 75. 今日のゴール✓ Railsアプリがセキュアかどうかを 確認するための、いくつかの基本的な チェック項目について知る✓ それぞれのチェック項目を満たすため の作戦を知る
  76. 76. セキュリティについてもう少し知りたくなったら OSC2008-do Ruby/Rails セキュリティハンズオン(仮) 開催日:2008年6月28日(土)  場所:さっぽろ産業振興センター 参加費:無料
  77. 77. セキュリティ以外について 知りたくなったら Railsレシピブック 高橋征義, 諸橋恭介(著) 発売日:2008年5月31日 出版社:ソフトバンククリエイティブ  価格:2940円(税込)
  78. 78. まとめ✓ Railsは標準でさまざまなセキュリ ティ対策をサポートしている✓ 重要なのはRailsによる対策のポイン トを理解すること✓ 用法・用量を守って正しくお使い下 さい
  79. 79. ご清聴 ありがとうございました

×