公開日:2007年6月28日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年6月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
ここでは、Webアプリケーションフレームワークが備えるセキュリティ機能に注目して、その利活用を検討していただく。
Webアプリケーションフレームワークとは、Webアプリケーションの骨組みを提供し、開発を助けてくれる仕組みのことをいう。Webアプリケーションに共通に必要な機能をいくつも備えているため、プログラマは、自分の問題を解決するコードの記述に集中できるようになる。
これまでに多くの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アプリケーションフレームワークには、次の傾向がみられる。
O/Rマッパ(Object-relational mapper)は、テーブルとローで構成されるリレーショナルデータベース要素へのアクセスを、プログラミング言語におけるクラスとインスタンスの操作を通じて行えるようにするライブラリである。
例えば、S2JDBCでは、次のようなJavaコードで検索を行うことができる。
List<Book> results
jdbcManager
.from (Book.class)
.where ("year = ? and price <= ?", givenYear, givenPrice)
.getResultList ();
O/Rマッパは、単にクラスとテーブルを対応づけるのみならず、1対1、1対多のようなテーブル間の結合をシンプルに扱える機能を備えている。
著名な Webアプリケーションフレームワークのひとつに、Ruby on Rails がある。以下、Rails と表記する。Rails は、プログラミング言語 Ruby を対象として作られたWebアプリケーションフレームワークである。2004年 7月に初めて登場し、2010年 8月29日にバージョン3 が、2013年 6月27日にバージョン4 がリリースされた。
Rails は、多くの機能を備えた部類のフレームワークである。主に次の機能を備えている。
Rails は、Ruby言語がもつ拡張性の高さを利用して作られている。Rubyでは、実行時にクラスの機能を拡張することができる。そのことを利用して、新しい「命令」をいくつも定義し、ひとつのクラスをドメイン固有言語(DSL)の処理系として使うことができる。
プログラミングの場面では、そのようにして定義された Rails 特有の「命令」を多数用いることになる。
Rails は、そのバージョン2 から、SQL注入等の著名な脆弱性への対応が考慮され始めたと言われている。それは、執筆時点の最新版(バージョン4.2)においても引き継がれて拡充されている。
Rails のセキュアプログラミング機能、およびセキュリティの考慮事項には、主に次のものがある。
これらのうち、a) ~ d) が、Ruby on Rails そのものが備えているものであり、e) ~ g) は、サードパーティによるプラグイン等が提供している機能である。a) ~ d) について、解説する。
Rails では(バージョン2以降)変数バインディング機能を用いることで、不用意な文字列連結によるSQL注入脆弱性の発生を回避できるようになっている。
例:
r3 = Persons.where("name = ?", params[:x])
これらの変数バインディングの実装であるが、Ruby on Rails の中のデータベース・アダプタ・クラスにおいて、それぞれのデータベース・ソフトウェアに応じた特殊文字のエスケープ処理を設けることによって実現されている。データベース・ソフトウェアの prepared statement 機能は利用されていない。
ところで、文字列連結によるSQL文の組み立てはAPI の上では禁止されていないので注意が必要である。例えば、次のような書き方は避けるべきである。
避けるべき例:
r3 = Persons.where("name = '#{params[:x]}'")
Rails 3 では、この ActiveRecord にも改造が施された。データベース・クエリに ARel と呼ばれるドメイン固有言語(DSL)が導入された。
ARel のプログラミングは、従来のようにSQL文全体を一度に記述するのではなく、select, from, where, group といった、SQLの構成要素に対応したメソッドを呼び出して、Relation クラスのインスタンスの上にクエリの条件を追加してゆくスタイルをとる。
ARel の導入で、例えば、次のようなメソッドが追加されている。
変数バインディングの機能が設けられているので、常にそれを用いることを推奨する。
クエリを断片ごとに記述する ARel のメソッド呼び出しは、見た目は異なっていても、相変わらずSQL文を操作しているのだという意識をもち、SQL注入脆弱性に用心する必要がある。
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 %>
Rails ではリクエスト強要(CSRF)対策の、フォームへのトークンの埋め込みとフォームデータを受信した際のトークンの照合が自動で行われる。
1) トークンの自動埋め込み
form_for 等のメソッドで生成するフォームには、自動でリクエスト強要(CSRF)対策のトークンが自動で埋め込まれる。Rails 2 ではトークンの固定値をプログラマが指定する形態が存在したが、Rails 3 では、処理系がランダムな値を生成するよう変わっている。
2) トークンの自動照合
コントローラ・クラスのビジネスロジックが呼び出される前に、リクエスト強要(CSRF)対策のトークンの照合が自動で行われる。ただし、照合が行われるのは次のようなHTTPリクエストの場合である。
このリクエスト強要(CSRF)対策のトークン自動照合は、Rails が備えている。before_filter という機能を用いて実現されている。この before_filter を用いると、ビジネスロジックと、そのビジネスロジックの呼出をWebクライアントに許すか否かのセキュリティロジックとを分離して配置することが可能である。
所定のセキュリティロジックを配置しておけば、プログラマはビジネスロジックの記述に集中することができ、また、ソースコードをシンプルに保つことができる。
Rails 4 からは「Strong Parameter」という機能によって Controller の段階で入力値のチェックを行うことができるようになった。
Webアプリケーションフレームワークは、アプリケーションプログラミングの負担を軽減してくれるのみならず、セキュアプログラミングに役立つ機能も備えるようになっている。また、フレームワークが、どのような脆弱性に自動で対策を施してくれて、プログラマはどのような問題に対処する必要があるかは、製品やそのバージョンによって様々である。
フレームワークを利用する際は、それらの点を見極めた上で、必要な脆弱性予防策を講じることが重要である。