アーカイブ
第3章 1.フレームワークの選択
公開日:2007年6月28日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年6月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
ここでは、Webアプリケーションフレームワークが備えるセキュリティ機能に注目して、その利活用を検討していただく。
開発環境となるフレームワーク
(1) プログラマが開発する部分は減る
Webアプリケーションフレームワークとは、Webアプリケーションの骨組みを提供し、開発を助けてくれる仕組みのことをいう。Webアプリケーションに共通に必要な機能をいくつも備えているため、プログラマは、自分の問題を解決するコードの記述に集中できるようになる。
-
図3-1: プログラマが開発する部分は減る
(2) プログラミング言語に依拠するフレームワーク
これまでに多くのWebアプリケーションフレームワークが作られ、さらに増えつつある。個々のフレームワークが提供する機能の多さや使い方には、さまざまなものがある。
各フレームワークのソフトウェアのスタイルに注目してみると、XMLで各種設定を詳しく記述するもの、「設定より規約(Convention over Configuration)」 のパラダイムから可能な限り設定ファイルへの記述を要しないようにするもの、出来合いのコンテンツ管理システム(CMS)の体裁をもちながら拡張のためのAPIを豊富に提供するもの、異なるフレームワークどうしを結びつけることを得意とするもの等、多様である。
| プログラミング言語 |
フレームワーク名 |
|---|---|
| Java |
Grails、Play、Spring、Apache Tapestry 等 |
| Ruby |
Ruby on Rails、Sinatra 等 |
| PHP |
CakePHP、 Lavarel、Symfony 等 |
| Python |
Django、TurboGears、Flask 等 |
| Perl |
Catalyst、Interchange、Mason 等 |
最近のフレームワークの傾向
最近のWebアプリケーションフレームワークには、次の傾向がみられる。
- 「モデル・ビュー・コントローラ」(MVC)モデルに沿って構成要素をプログラミングする
- 「設定より規約」(Convention over Configuration)方式で構成要素を結びつける
- リレーショナルデータベースアクセスのためのO/Rマッパが付属しているか、既存のO/Rマッパと親和性がある
O/Rマッパ
O/Rマッパ(Object-relational mapper)は、テーブルとローで構成されるリレーショナルデータベース要素へのアクセスを、プログラミング言語におけるクラスとインスタンスの操作を通じて行えるようにするライブラリである。
-
図3-2: O/Rマッパ
例えば、S2JDBCでは、次のようなJavaコードで検索を行うことができる。
List<Book> results
jdbcManager
.from (Book.class)
.where ("year = ? and price <= ?", givenYear, givenPrice)
.getResultList ();
O/Rマッパは、単にクラスとテーブルを対応づけるのみならず、1対1、1対多のようなテーブル間の結合をシンプルに扱える機能を備えている。
Ruby on Rails とセキュアプログラミング
(1) Ruby on Rails
著名な Webアプリケーションフレームワークのひとつに、Ruby on Rails がある。以下、Rails と表記する。Rails は、プログラミング言語 Ruby を対象として作られたWebアプリケーションフレームワークである。2004年 7月に初めて登場し、2010年 8月29日にバージョン3 が、2013年 6月27日にバージョン4 がリリースされた。
Rails は、多くの機能を備えた部類のフレームワークである。主に次の機能を備えている。
- Web アプリケーションの基本構造
- セッション維持の仕組み
- HTTPリクエストと処理モジュールのマッピング
- テンプレートエンジンによる Webページの生成
- 入力検査の仕組み
- ユーザ認証とアクセス認可の仕組み
- データベースアクセス(O/R マッピング[注]等)
- REST サポート(URLのマッピング)
- Ajax サポート
- キャッシュ 等
Rails は、Ruby言語がもつ拡張性の高さを利用して作られている。Rubyでは、実行時にクラスの機能を拡張することができる。そのことを利用して、新しい「命令」をいくつも定義し、ひとつのクラスをドメイン固有言語(DSL)の処理系として使うことができる。
プログラミングの場面では、そのようにして定義された Rails 特有の「命令」を多数用いることになる。
(2) Rails 上のセキュアプログラミング
Rails は、そのバージョン2 から、SQL注入等の著名な脆弱性への対応が考慮され始めたと言われている。それは、執筆時点の最新版(バージョン4.2)においても引き継がれて拡充されている。
Rails のセキュアプログラミング機能、およびセキュリティの考慮事項には、主に次のものがある。
- 著名な脆弱性対策
- a) SQL注入対策
- b) スクリプト注入対策
- c) リクエスト強要(CSRF)対策
- 入力値対策
- d) 入力値検査
- e) Taintを利用した入力値追跡
- 計画的なセキュリティ機能性
- f) ユーザ認証
- g) アクセス認可
これらのうち、a) ~ d) が、Ruby on Rails そのものが備えているものであり、e) ~ g) は、サードパーティによるプラグイン等が提供している機能である。a) ~ d) について、解説する。
a) SQL注入対策
Rails では(バージョン2以降)変数バインディング機能を用いることで、不用意な文字列連結によるSQL注入脆弱性の発生を回避できるようになっている。
例:
r3 = Persons.where("name = ?", params[:x])
これらの変数バインディングの実装であるが、Ruby on Rails の中のデータベース・アダプタ・クラスにおいて、それぞれのデータベース・ソフトウェアに応じた特殊文字のエスケープ処理を設けることによって実現されている。データベース・ソフトウェアの prepared statement 機能は利用されていない。
ところで、文字列連結によるSQL文の組み立てはAPI の上では禁止されていないので注意が必要である。例えば、次のような書き方は避けるべきである。
避けるべき例:
r3 = Persons.where("name = '#{params[:x]}'")
Rails 3 のO/Rマッパーのメソッド
Rails 3 では、この ActiveRecord にも改造が施された。データベース・クエリに ARel と呼ばれるドメイン固有言語(DSL)が導入された。
ARel のプログラミングは、従来のようにSQL文全体を一度に記述するのではなく、select, from, where, group といった、SQLの構成要素に対応したメソッドを呼び出して、Relation クラスのインスタンスの上にクエリの条件を追加してゆくスタイルをとる。
ARel の導入で、例えば、次のようなメソッドが追加されている。
- Rails 3 から追加されたメソッド
- select, from, where, group, having, includes, joins,
limit, order, reorder,
create_with, eager_load, preload
average, calculate, count, maximum, minimum, sum 等
- select, from, where, group, having, includes, joins,
- Rails 2 までに存在していたメソッド
- find, first, last, all, exists?, count_by_sql, find_by_sql,
create, update, update_all, delete_all, destroy_all 等
- find, first, last, all, exists?, count_by_sql, find_by_sql,
変数バインディングの機能が設けられているので、常にそれを用いることを推奨する。
クエリを断片ごとに記述する ARel のメソッド呼び出しは、見た目は異なっていても、相変わらずSQL文を操作しているのだという意識をもち、SQL注入脆弱性に用心する必要がある。
b) スクリプト注入対策
Rails 2 では、出力ページのERBテンプレート(rhtmlファイル)に例えば次のような記述をすることによって、& " < > の記号にエスケープ処理を施した上で値を出力させることができる。
Rails 2 の例
<%= h @name %>
この h メソッドは、ERB::Util クラスの html_escape メソッドの別名である。
Rails 3 では、ERBテンプレートにおける h メソッドの適用がデフォルトになった。
Rails 3 の例
<%= @name %>
何も書かなければ、h メソッドによるエスケープ処理が適用される。これに伴い、逆に、このエスケープ処理を敢えて行わせないための raw メソッドが導入された。
Rails 3 の例(推奨はしない)
<%= raw @name %>
c) リクエスト強要(CSRF)対策
Rails ではリクエスト強要(CSRF)対策の、フォームへのトークンの埋め込みとフォームデータを受信した際のトークンの照合が自動で行われる。
1) トークンの自動埋め込み
form_for 等のメソッドで生成するフォームには、自動でリクエスト強要(CSRF)対策のトークンが自動で埋め込まれる。Rails 2 ではトークンの固定値をプログラマが指定する形態が存在したが、Rails 3 では、処理系がランダムな値を生成するよう変わっている。
2) トークンの自動照合
コントローラ・クラスのビジネスロジックが呼び出される前に、リクエスト強要(CSRF)対策のトークンの照合が自動で行われる。ただし、照合が行われるのは次のようなHTTPリクエストの場合である。
- POSTで送信されるフォームデータに限られる。
- protect_from_forgery 命令によって指定されたコントローラ・クラスとメソ ッドの範囲。デフォルトの保護対象は、すべてのコントローラクラスの全メソッド(ただしPOSTで呼ばれるもの)である。
このリクエスト強要(CSRF)対策のトークン自動照合は、Rails が備えている。before_filter という機能を用いて実現されている。この before_filter を用いると、ビジネスロジックと、そのビジネスロジックの呼出をWebクライアントに許すか否かのセキュリティロジックとを分離して配置することが可能である。
所定のセキュリティロジックを配置しておけば、プログラマはビジネスロジックの記述に集中することができ、また、ソースコードをシンプルに保つことができる。
d) 入力値対策
Rails 4 からは「Strong Parameter」という機能によって Controller の段階で入力値のチェックを行うことができるようになった。
まとめ
Webアプリケーションフレームワークは、アプリケーションプログラミングの負担を軽減してくれるのみならず、セキュアプログラミングに役立つ機能も備えるようになっている。また、フレームワークが、どのような脆弱性に自動で対策を施してくれて、プログラマはどのような問題に対処する必要があるかは、製品やそのバージョンによって様々である。
フレームワークを利用する際は、それらの点を見極めた上で、必要な脆弱性予防策を講じることが重要である。