20080521-ruby-on-rails-security

79
2008-05-21(水); Apple Store Sapporo Ruby Sapporo Night vol.6 Ruby on Rails Security 島田浩二 SHIMADA Koji; Nihon Ruby-no-kai; RubySapporo 日本Rubyの会 Ruby札幌 [email protected] 入門 Rails セキュリティ

Upload: koji-shimada

Post on 12-Nov-2014

3.860 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: 20080521-Ruby-on-Rails-Security

2008-05-21(水); Apple Store SapporoRuby Sapporo Night vol.6

Ruby on Rails Security

島田浩二SHIMADA Koji; Nihon Ruby-no-kai; RubySapporo

日本Rubyの会Ruby札幌[email protected]

入門 Railsセキュリティ

Page 2: 20080521-Ruby-on-Rails-Security

Tell The Topic of Ruby, RubySapporo!

Ruby札幌、Rubyの話しろ!

Page 3: 20080521-Ruby-on-Rails-Security

しまだこうじhttp://iddy.jp/profile/snoozer05

✓ ふつうのフリーランス・プログラマ✓ 日本Rubyの会

✓ Ruby札幌 運営✓ RubyKaigi スタッフ/実行委員

✓ プログラミングの楽しさを共有したい✓ 自分の知らないコトやヒトに出会いたい

Page 4: 20080521-Ruby-on-Rails-Security

どうぞよろしくお願いします

Page 5: 20080521-Ruby-on-Rails-Security

まとめ

✓ Railsは標準でさまざまなセキュリティ対策をサポートしている

✓ 重要なのはRailsによる対策のポイントを理解すること

✓ 用法・用量を守って正しくお使い下さい

Page 6: 20080521-Ruby-on-Rails-Security

今日のゴール

✓ Railsアプリがセキュアかどうかを確認するための、いくつかの基本的なチェック項目について知る

✓ それぞれのチェック項目を満たすための作戦を知る

Page 7: 20080521-Ruby-on-Rails-Security

チェックリスト

Page 8: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 9: 20080521-Ruby-on-Rails-Security

一つずつ

Page 10: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 11: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

チェック項目1

Page 12: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

Page 13: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

Page 14: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

Page 15: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

Page 16: 20080521-Ruby-on-Rails-Security

見せなくてよい情報を公開していないか

422ステータスのテンプレートがデフォルトで用意されているのは

Rails2.0~

Page 17: 20080521-Ruby-on-Rails-Security

何が起きるか✓ 攻撃者に攻撃方法を考えるヒントを与えてしまう✓ フレームワークや固有のバージョンの脆弱性をつかれる可能性がある

Page 18: 20080521-Ruby-on-Rails-Security

対策✓ 攻撃のヒントになる可能性のある情報は、極力表に出さない✓ デフォルトのページなどをそのままにしない✓ アクセス制御をきちんと

Page 19: 20080521-Ruby-on-Rails-Security

ActionController::Routing:: Routes.draw do |map| … map.root :controller => "welcome" …end

config/routes.rb

トップページが指定された場合のルーティング先を定義

対策

Page 20: 20080521-Ruby-on-Rails-Security

各種デフォルトのテンプレートをきちんと差し替える

対策

Page 21: 20080521-Ruby-on-Rails-Security

…<DirectoryMatch "^/.*/\.svn/"> ErrorDocument 403 /404.html Order allow,deny Deny from all Satisfy All </DirectoryMatch>…

httpd.conf

Webサーバでファイルのアクセスに関する適切な設定を行う

対策

Page 22: 20080521-Ruby-on-Rails-Security

✓ 攻撃のヒントになる可能性のある情報は、極力表に出さない✓ デフォルトのページなどをそのままにしない✓ ステータスページ等

✓ アクセス制御をきちんと✓ サーバの設定などをきちんと確認

見せなくてよい情報を公開していないか

Page 23: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 24: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 25: 20080521-Ruby-on-Rails-Security

重要なモデル属性を保護できているか

チェック項目2

Page 26: 20080521-Ruby-on-Rails-Security

create_table :users do |t| t.string :login t.string :name t.string :password t.integer :admin, :default => 0end

db/migrate/00X_create_users.rb

class Users < ActiveRecord::Baseend

制御に絡む属性app/models/user.rb

重要なモデル属性を保護できているか

Page 27: 20080521-Ruby-on-Rails-Security

create_table :users do |t| t.string :login t.string :name t.string :password t.integer :admin, :default => 0end

db/migrate/00X_create_users.rb

class Users < ActiveRecord::Baseend

制御に絡む属性app/models/user.rb

重要なモデル属性を保護できているか

何のガードもしていない

Page 28: 20080521-Ruby-on-Rails-Security

http://example.com/users/new

重要なモデル属性を保護できているか

Page 29: 20080521-Ruby-on-Rails-Security

http://example.com/users/new

重要なモデル属性を保護できているか

Page 30: 20080521-Ruby-on-Rails-Security

何が起きるか✓ 攻撃者の視点✓ このフォームを使って何か攻撃できないか✓ フィールドにありそうな属性でも追加してみるか

✓ ユーザ情報だったら管理者権限か✓ とりあえずadminあたりから

Page 31: 20080521-Ruby-on-Rails-Security

何が起きるか

<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>

オリジナルのフォーム

Page 32: 20080521-Ruby-on-Rails-Security

何が起きるか

改変されたフォーム

<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>

Page 33: 20080521-Ruby-on-Rails-Security

何が起きるか

改変されたフォーム

<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>

フォームを改変されて使用されると公開していない属性でも上書きされてしまう

Page 34: 20080521-Ruby-on-Rails-Security

対策✓ 制御に絡む属性はきちんと保護する✓ フォームからのリクエストで直で更新しない✓ ARが提供している仕組みを利用する✓attr_protected, attr_accesible

Page 35: 20080521-Ruby-on-Rails-Security

class Users < ActiveRecord::Base attr_protected :adminend

attr_protectedのサンプル

class Users < ActiveRecord::Base attr_accesible :login, :name, :passwordend

指定した属性以外は一括代入時には無視される

対策

attr_accesibleのサンプル

指定した属性は一括代入時には無視される

Page 36: 20080521-Ruby-on-Rails-Security

✓ 制御に絡む属性はきちんと保護する✓ フォームからのリクエストで直で更新しない✓ ARが提供している仕組みを利用する✓attr_protected, attr_accesible✓開発当初はattr_protectedを使用し、開発が進み制御に絡む属性が増えてきたらattr_accesibleへ切り替えるのが吉

重要なモデル属性を保護できているか

Page 37: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 38: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 39: 20080521-Ruby-on-Rails-Security

コントローラメソッドが公開されていないか

チェック項目3

Page 40: 20080521-Ruby-on-Rails-Security

app/controllers/users_controller.rb

class UsersController < ApplicationController # 外部に公開しているアクション def activate mark_as_activate if valid_request end # 具体的にアクティベート化を行う処理 def mark_as_activate ... endend

publicメソッドとして定義してしまっている

コントローラメソッドが公開されていないか

Page 41: 20080521-Ruby-on-Rails-Security

何が起きるか✓ 内部処理が外部からアクションとして呼べてしまう✓ ブラウザ等から容易に実行できてしまう✓ 悪意がなくても踏んでしまう危険性がある

✓ 一度でも呼ばれると、システムの整合性は保証できない

Page 42: 20080521-Ruby-on-Rails-Security

対策✓ コントローラメソッドのアクセス制御をきちんと管理する✓ アクションではないメソッドはpublicにしない

✓ アクセス制御の明示✓private, protected

Page 43: 20080521-Ruby-on-Rails-Security

対策

class UsersController < ApplicationController def activate mark_as_activate if valid_request end

private def mark_as_activate ... endend

app/controllers/users_controller.rb

Page 44: 20080521-Ruby-on-Rails-Security

コントローラメソッドが公開されていないか

✓ コントローラメソッドのアクセス制御をきちんと管理する✓ アクションではないメソッドはpublicにしない

✓ アクセス制御の明示✓private, protected

Page 45: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 46: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 47: 20080521-Ruby-on-Rails-Security

出力ページのエスケープ処理に漏れはないか

チェック項目4

Page 48: 20080521-Ruby-on-Rails-Security

app/views/users/show.erb.rhtml

...<p> <b>Name:<b> <%= @user.name %></p> ...

hメソッドによる、特殊文字のHTMLエンティティとしてのエスケープ処理が漏れている

出力ページのエスケープ処理に漏れはないか

Page 49: 20080521-Ruby-on-Rails-Security

何が起きるか✓ クロスサイト・スクリプティング攻撃(XSS)✓ 攻撃者が埋め込んだ任意のスクリプトが出力ページ内に挿入されてしまう

✓ ページの訪問者のCookie情報が盗み取られる等、致命的な被害を引き起こす入り口

Page 50: 20080521-Ruby-on-Rails-Security

対策✓ 出力ページのエスケープ処理について漏れがないことを確認する✓ SafeERBプラグインを使用しエスケープ漏れを検出

✓ sanitizeメソッドを使用しホワイトリスト形式で出力時にスクリプトを除去

Page 51: 20080521-Ruby-on-Rails-Security

対策✓ SafeERB✓ http://agilewebdevelopment.com/plugins/safe_erb✓ taint機構を使ってエスケープ漏れをチェック

✓ エスケープ漏れがあると例外✓ SQLiteから取り出した値はtaintedではないので例外が出ないので注意→確認する場合はPostgresやMySQLで

Page 52: 20080521-Ruby-on-Rails-Security

対策✓ sanitizeメソッド✓ ホワイトリスト方式を使用し任意のタグを除去

...<p> <b>Name:<b> <%= sanitaize(@user.name) %></p> ...

app/views/users/show.erb.rhtml

Page 53: 20080521-Ruby-on-Rails-Security

✓ 出力ページのエスケープ処理について漏れがないことを確認する✓ SafeERBプラグインを使用しエスケープ漏れを検出

✓ sanitizeメソッドを使用しホワイトリスト形式で出力時にスクリプトを除去

出力ページのエスケープ処理に漏れはないか

Page 54: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 55: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 56: 20080521-Ruby-on-Rails-Security

DBへ渡す入力のエスケープ処理に漏れはないか

チェック項目5

Page 57: 20080521-Ruby-on-Rails-Security

app/controllers/user_controller.rb

DBへ渡す入力のエスケープ処理に漏れはないか

Page 58: 20080521-Ruby-on-Rails-Security

app/controllers/user_controller.rb

ユーザ入力をそのままSQLへ変換してしまっているためエスケープ処理が行われていない

DBへ渡す入力のエスケープ処理に漏れはないか

Page 59: 20080521-Ruby-on-Rails-Security

app/controllers/user_controller.rb

ユーザ入力をそのままSQLへ変換してしまっているためエスケープ処理が行われていない

DBへ渡す入力のエスケープ処理に漏れはないか

Page 60: 20080521-Ruby-on-Rails-Security

何が起きるか✓ SQLインジェクション✓ サーバ上で実行されるSQLを攻撃者が制御可能になってしまう

✓ データベースを不正操作され致命的な被害を引き起こす

Page 61: 20080521-Ruby-on-Rails-Security

対策✓ SQLの組み立てにはバインド変数を使用しSQLのメタ文字をエスケープする✓ ?プレースホルダの使用して値を指定✓ 名前付きバインド変数のハッシュを使用

Page 62: 20080521-Ruby-on-Rails-Security

✓ プレースホルダの使用

対策

User.find(:first, :conditions => [“name = ?”, params[:name]])

User.find(:all, :conditions => [“category IN (?)”,[1, 2, 3]])

Page 63: 20080521-Ruby-on-Rails-Security

✓ 名前付きバインド変数の使用

対策

User.find(:first, :name => params[:name], :password => params[:password])

User.find(:first, :conditions => [“name = :name”, :name => params[:name]])

Page 64: 20080521-Ruby-on-Rails-Security

✓ SQLの組み立てにはバインド変数を使用しSQLのメタ文字をエスケープする✓ ?プレースホルダの使用して値を指定✓ 名前付きバインド変数のハッシュを使用

DBへ渡す入力のエスケープ処理に漏れはないか

Page 65: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 66: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 67: 20080521-Ruby-on-Rails-Security

外部ページからの不正なリクエストをガードできているか

チェック項目7

Page 68: 20080521-Ruby-on-Rails-Security

外部からの不正なリクエストをガードできているか

class BlogsController < ApplicationController ... def update ... end ...end

app/controllers/blogs_controller.rb

<% form_for(@blog) do |f| %> ...<% end %>

app/views/blog/edit.rhtml

リクエスト処理に対して何もガードをかけていない

Page 69: 20080521-Ruby-on-Rails-Security

何が起きるか✓ クロスサイトリクエストフォージ(CSRF)✓ 攻撃者の誘導により、ユーザが外部ページから攻撃者の用意したリクエストを実行してしまう

Page 70: 20080521-Ruby-on-Rails-Security

対策✓ リクエストの有効性を検証する✓ Rails2.0からはデフォルトで対策の処理が入っている✓ protect_from_forgery✓ ApplicationControllerクラスで指定✓ Railsの生成するフォームと対で検証用のトークンを持ち、それらを比較することでリクエストの有効性を評価

Page 71: 20080521-Ruby-on-Rails-Security

✓ protect_from_forgeryの使用

対策

class ApplicationController < ActionController::Base protect_from_forgery end

class BlogController < ApplicationController::Base protect_from_forgery :only => [:create,:update] end

Page 72: 20080521-Ruby-on-Rails-Security

✓ リクエストの有効性を検証する✓ Rails2.0からはデフォルトで対策の処理が入っている✓ protect_from_forgery✓ ApplicationControllerクラスで指定✓ Railsの生成するフォームと対で検証用のトークンを持ち、それらを比較することでリクエストの有効性を評価

外部からの不正なリクエストをガードできているか

Page 73: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 74: 20080521-Ruby-on-Rails-Security

チェックリスト

1. 見せなくてよい情報を公開していないか

2. 重要なモデル属性を保護できているか

3. コントローラメソッドが公開されていないか

4. 出力ページのエスケープ処理に漏れはないか

5. DBへ渡す入力のエスケープ処理に漏れはないか

6. 外部ページからの不正なリクエストをガードできているか

Page 75: 20080521-Ruby-on-Rails-Security

今日のゴール

✓ Railsアプリがセキュアかどうかを確認するための、いくつかの基本的なチェック項目について知る

✓ それぞれのチェック項目を満たすための作戦を知る

Page 76: 20080521-Ruby-on-Rails-Security

OSC2008-doRuby/Railsセキュリティハンズオン(仮)開催日:2008年6月28日(土) 場所:さっぽろ産業振興センター参加費:無料

セキュリティについてもう少し知りたくなったら

Page 77: 20080521-Ruby-on-Rails-Security

セキュリティ以外について知りたくなったら

Railsレシピブック高橋征義, 諸橋恭介(著)発売日:2008年5月31日出版社:ソフトバンククリエイティブ 価格:2940円(税込)

Page 78: 20080521-Ruby-on-Rails-Security

まとめ

✓ Railsは標準でさまざまなセキュリティ対策をサポートしている

✓ 重要なのはRailsによる対策のポイントを理解すること

✓ 用法・用量を守って正しくお使い下さい

Page 79: 20080521-Ruby-on-Rails-Security

ご清聴ありがとうございました