公開日:2007年6月28日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年6月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
ここで述べるのは、脆弱性が生まれにくいWebアプリケーションを構築するために設計段階、あるいはそれ以前の段階で考慮しておくとよい事項の例である。
今日のWEBアプリケーション開発環境は、プログラミング言語の処理系に加えて、開発フレームワークやコンテンツ管理システム(CMS)、さらに外部のテンプレート言語までを加えた総合的な環境となってきている。
短時日で素早くサイトを立ち上げることを目的として、「軽量言語」と呼ばれる各種スクリプト言語が標準で備えているWEBアプリケーションを手軽に開発するための機能やライブラリをそのまま利用することは悪くない。しかし、その手軽さ故に、セキュリティの観点からは多くの脆弱性を生んできた経緯がある。
例えば、下記の事例が挙げられる。
開発環境の仕様について十分な知識とスキルを有する開発要員を確保できない場合、そのような環境を避けるという選択肢もある。
大規模なシステムにおいては下記のような考慮事項があるが、フレームワークにはこれらを支援する機能がある。
Webアプリケーションのセキュリティにおいてセッション管理の設計が肝要であり、大規模システムにおけるセッション管理は複雑なものとなる。複雑なセッション管理を適切に設計するためにもフレームワークが提供する機能を利用することは有用である。
データベースをSQLでアクセスする構造を採用するのであれば、WebアプリケーションはSQL注入攻撃の危険に曝される。データベース製品を選択する際にはその製品およびDBアクセスAPIがどのような特徴を持っているかあらかじめ把握しておくとよい。
用途の異なるコンテンツがひとつのサイトに混在しないよう、複数のサイトへの分離をはかる。
http:専用サイト と https:専用サイト を分ける
同じサイト上にhttp:ページとhttps:ページが混在しないようにできるのであれば、https:専用サイトのCookieが平文でネットワークに流出する問題を防ぎやすい
商品カタログサイト と ショッピングカートサイト を分ける
会員向けサイト と 管理者向けサイト を分ける 等
あらかじめサイトを分離しておくことで、アクセス制御(本人認証とアクセス認可)のロジックが複雑になるのを避けることができる。これは、アクセス制御が迂回される脆弱性を起こりにくくする効果がある。
ユーザ認証をどの方式で行うか決める。
例えば、各コンテンツの冒頭にてアクセス認可を次のように実装する。
ユーザがログインに成功したら次を行う。
ユーザがログインに成功したら次を行う。
https:は、ログインページや個人情報入力・表示ページのみならず、ログインの状態を追跡する場面でも使用する。
ユーザ認証データがブラウザからサーバへ送られるすべての通信でhttps:を使用する
ログインの時点で新しい値が与えられたセッションIDがやりとりされるすべての通信でhttps:を使用する
ログインの時点で発行されたログイン追跡パラメータがやりとりされるすべての通信でhttps:を使用する
ひとつの対策は、セッション変数に入力値を保持するのではなく、入力途中においてはそれまでの入力値をhiddenパラメータで持ち歩くというものである。ただし、入力値をhiddenパラメータの値としてHTMLに埋め込む際、スクリプト注入(クロスサイトスクリプティング)対策が必要である
本物であることの確認手段を封じないウィンドウレイアウトデザインをする
エラーの種類に応じた画面遷移を設計する
チェックボックス、ラジオボタン、選択肢項目等、ユーザが直接値を入力しないフォーム項目も、悪意あるユーザによって値が改ざんされているおそれがある。
これらの選択項目については、次のように取り扱う。
これにより、外部からプログラムに不正な値が送り込まれる機会を減らすことができる。
推奨しない例
<select name="pref">
<option value="北海道">北海道
<option value="青森県">青森県
<option value="岩手県">岩手県
<option value="宮城県">宮城県
<option value="秋田県">秋田県
...
</select>
→ 入力パラメータ pref の値をデータベースに格納
推奨例
<select name="pref">
<option value="01">北海道
<option value="02">青森県
<option value="03">岩手県
<option value="04">宮城県
<option value="05">秋田県
...
</select>
→ 入力パラメータ pref の値が2桁の数字であることをチェック
→ 値が 01~47 の範囲内であることをチェック
→ 2桁のコードをデータベースに格納