「安全なWebアプリケーションの作り方」を読んでみて思ったこと

# はじめに

今回はプリザンターというWebアプリを扱っているため、Webアプリの作り方を参考にセキュリティについて考えようと思い後述の書籍を読むことにしました。  
本記事では[Webフロントエンド ハイパフォーマンス チューニング](https://gihyo.jp/book/2017/978-4-7741-8967-3)の内容を個人的に大切だと思った内容に絞って解説します。要約した内容ではありませんのでご容赦ください。  

# 全体的な感想

本書は色々な攻撃方法とその対策が記載されています。そのため、実際の本書の内容をすべて記載しようと思うと膨大な量になるため、「SQLインジェクション」に絞って記載します。また、「ログの出力」に関しては現在のわたしにもっとも必要な内容だと思いましたため、こちらを重点的に記載しようと思います。

# 前提

本書はタイトルの通り、セキュリティに関する書籍です。内容としては、Webアプリの脆弱性や攻撃手法、その対策がまとめられています。そのため、これからwebアプリを作成する人や今作成している人、そのような業務に携わっている人が対象になるかと思います。また、知らないうちに犯罪に巻き込まれないためにもアプリの利用者も本書をオススメいたします。

# 脆弱性

まず、webアプリには脆弱性が存在してはいけません。その理由として下記が挙げられます。

1. 経済的損失
   * 利用者への金銭的補填
   * 社会的信頼の減少
   * 損害賠償
2. 法的な要求
   * 個人情報保護法
3. 利用者への回復不能なダメージ
   * 流出した個人情報は回復不可能
   * 利用者への不安等はお金で解決できない
4. 攻撃に加担してしまう

以上の理由からweアプリに脆弱性はあってはいけません。

# クッキーが盗まれる

クッキーにはセッションIDが含まれます。セッションIDとは簡単にいうとログイン情報を特定するためのIDです。そのため、クッキーを盗まれてしまうと自分のアカウントを他人が乱用できてしまいます。もし、アプリに脆弱性があり、誰かのクッキーを盗めるような環境だと大変なことが起こるのは目に見えて分かります。そうならないためにも脆弱性は可能な限り存在させてはいけません。

# エラーメッセージ

エラーメッセージは画面に表示してはいけません。なぜなら、エラーメッセージには内部情報が含まれているからです。そのため、エラーメッセージを表示させるのではなく、エラー専用の画面を用意し、エラーになったらその専用画面に遷移するように実装します。

# SQLインジェクション

DBと連携したアプリの多くはクライアントからの入力情報をもとにSQL分を組み立てています。このSQL文の組み立て方に問題があるとSQLインジェクションが発生します。  
SQLインジェクションの発生を防ぐ方法として下記があります。  

1. エラーメッセージを画面に表示しない
2. 入力値の検証
   * 静的プレースホルダーを使用する
3. データベースの権限設定
   * それぞれの使用用途に合わせて権限設定をする(検索ページであれば、参照権限の身にする等)

本書ではそのほかにたくさんの攻撃手法を取り上げていますが、すべてを取り上げると切がないため、SQLインジェクション攻撃のみ記載いたします。  

## プレースホルダー

プレースホルダーとは、SQLに動的な値を設定する記述方法です。画面上からユーザIDやパスワードを入力した際にSQL文に使うものですね。  
プレースホルダーには、「静的プレースホルダー」と「動的プレースホルダー」があるようです。それぞれ下記に記載いたします。  

* 静的プレースホルダー  
  プレースホルダーを含んだSQL文をデータベースに送り、コンパイル等の実行準備が行われ、SQL文が確定します。  
  →後からSQL文が変更される可能性は原理的にあり得ません。  
* 動的プレースホルダー  
  プレースホルダーを含んだSQL文をアプリ側で処理しSQL文を確定します。  
  →処理に問題がなければSQLインジェクションは発生しません。  

あくまでも、静的プレースホルダーのほうが良いという考えです。  

# ログ出力

アプリケーションが生成するログはセキュリティの面からも重要です。  

## 目的

アプリケーションが生成するログはセキュリティの面からも重要である理由は下記の通りです。  

1. 攻撃や自己の予兆をログから把握し、早朝に対策するため
2. 攻撃や自己の事後調査のため
3. アプリケーションの運用監査のため
攻撃の予兆をログから調べるにはログイン試行やログインエラーの回数をログに出力します。これにより、通常よりも回数が多くなっている場合、外部からの攻撃の可能性があると判断できます。  
一方、アプリが攻撃されて被害が出た場合には、攻撃の状況の調査をする必要があり、ログが重要になります。ログが残っていない、あるいは必要な情報がログにない場合、調査が十分にできない可能性があります。  

## 種類

アプリケーションに関係するログには以下の種類があります。  

1. Webサーバ(Apache, Nginx, IISなど)のログ
2. アプリケーションログ
3. データベースログ
アプリケーションログについては以下のように分けられます。
1. エラーログ
2. アクセスログ
3. デバッグログ
上記3つのログの詳細については下記です。  

### エラーログ

エラーログは、文字通りアプリケーションのさまざまなエラーを記録するものです。アプリケーションでエラーが発生した場合、利用者向けのメッセージを表示し、エラーの詳しい内容や原因はログに出力するようにします。エラーの内容が攻撃者にとってのヒントになる可能性があるという理由からです。  
エラーログは攻撃の検出に役立つ場合があります。SQLインジェクションやディレクトリ・バーサル攻撃等の試行中には、SQLのエラーやファイルオープンのエラーが発生しやすくなります。このようなエラーは通常発生しないはずのものであるため、エラーが続けて発生する場合は攻撃を疑う必要があります。  

### アクセスログ

アクセスログはアプリケーションの情報閲覧や機能の利用記録としてのログです。エラーログとは異なり、正常・異常ともにログに残します。  
上記で記載した「目的」を達成するためには正常系のアクセスログが必要であることからもアクセスログの重要性がわかります。  

### デバッグログ

デバッグログは文字通りデバッグ用のログのことです。デバッグログを生成するとログのデータ量が膨大になり、パフォーマンスに影響が出る場合もあります。また、デバッグログから個人情報やクレジットカード情報が漏洩した事例もあります。デバッグログは開発環境やテスト環境で取得すべきもので、本番環境ではデバッグログを取得するべきではありません。  

## ログの出力要件

ログ出力に関する要件を以下の観点から説明します。  

1. ログに記録すべきイベント
2. ログの出力項目
3. ログの保護
4. ログの出力先
5. ログの保管期間
6. サーバの時刻合わせ

### ログに記録すべきイベント

ログに記録すべきイベントは多すぎても少なすぎてもダメで、ログの使用目的から決定すべきです。しかし、一般的にはいかに示す認証・アカウント管理や重要な情報や操作に関するイベントを記録します。  

1. ログイン・ログアウト(いっぱいを含む)
2. アカウントロック
3. ユーザ登録・削除
4. パスワード変更
5. 重要情報の参照
6. 重要な操作(物品の購入、送金、メール送信など)

### ログの出力項目

ログの出力高億は4W1H(いつ、誰が、どこで、何を、どのように)に従った以下の項目を取得します。  

1. アクセス日時
2. リモートIPアドレス
3. ユーザID
4. アクセス対象(URL、ページ番号、スクリプトIDなど)
5. 操作内容(閲覧、変更、削除等)
6. 操作対象(リソースIDなど)
7. 操作結果(成功あるいは失敗、処理件数など)
また、監査等では複数のログを突き合わせ処理することが多いため、ログの出力フォーマットを統一するとログ利用の上で便利です。  

### ログの保護

ログが改ざん・削除されるとログが目的を達成できないため、ログに対する不正アクセスができないよう保護する必要があります。また、ログファイル自体に個人情報等機密情報を含めないように制限するか、項目を省略できない場合はマスク処理等を施します。いずれの場合でも、ログにパスワードやクレジットカード情報を含めてはいけません。  
これらログの施策のため、可能であれば、ログを保存するサーバはWebサーバやDBサーバとは別に用意し、サイト管理者とは別にログの管理者を割り当てることが好ましいでしょう。  

### ログの出力先

ログの出力先には、DBやファイルがよく用いられますが、前項で述べたログの保護という目的からはログ専用のサーバを用意することが望ましいです。ただし費用がかかることなので、ログ専用サーバ導入の採否は要件として検討します。  

### ログの保管期間

Webサイトの特性に合わせてログの保管期間を運用ルールとして定めます。しかし、セキュリティ上の事件や事故の事後調査という目的を考慮すると、ログの保管期間を定めるのは難しく、無期限で保存するという考え方もあります。  
一方、ログ自体に誤って機密情報が含まれていた場合、保管期限を伸ばすと情報漏洩の危険性が増加するというジレンマもあります。定期的にログファイルを暗号化して長期保管に適した別のメディアに記録し、普段は安全な場所に記録メディアを保管するなど運用を工夫していく必要があります。  

### サーバの時刻合わせ

ログは単体でぞんざいするものではなく、Webサーバ、アプリケーション、DB、メール等さまざまなログを組み合わせて調査などに用います。これら複数ログを突き合わせられるように各サーバの時刻を同期させる必要があります。  
この目的のためには、NTPというプロトコルを用いてサーバの時刻を合わせることが良く行われます。  

### ログ出力の実装

ログ出力は通常のファイルアクセス機能やデータベースアクセス機能を使っても実装することは可能ですが、ログ特有の要求を考慮して設計されたログ出力用のライブラリが開発されています。  

### アクセスログを要求するガイドライン

政府や各種団体の公開しているセキュリティガイドラインには、アクセスログの取得を義務付けているものがあります。ここではその中から以下を紹介します。  

* 個人情報の保護に関する法律(個人情報保護法)
* 金融商品取引法の要求する内部統制報告書
* Payment Card Industry (PCI) データセキュリティ基準 (PCI DSS)

### 個人情報の保護に関する法律(個人情報保護法)

個人商法保護法では、個人情報に対する「安全管理措置」を求めています。安全管理措置の具体的な方法については、従来は各省庁から事業分野ごとのガイドラインが出ていましたが、改正個人情報保護法の試行に伴い、個人情報保護委員会が定めるガイドラインに原則一元化されました。  

#### 個人情報の保護に関する法律についてのガイドライン（通則編）

不正アクセス検知を目的としてログの定期的な分析を求めています。また、ログにより整備された個人データの取り扱いにかかる規律に従った運用の状況を確認する事も求めています。  

### 金融商品取引法の要求する内部統制報告書

金融商品取引法では、上場企業の財務諸表の信頼性評価を目的として、上場企業に対して内部統制報告書の提出を義務付けています(J-SOX)。J-SOXでは、内部統制が有効に機能していることを証明するための監査が重要視されており、財務計算に影響を及ぼす企業システムのログ取得の重要性が増しました。  
経産省は内部統制に求められるITへの対応を明確にしていますが、その中でログの必要性が例示されています。  

### Payment Card Industry (PCI) データセキュリティ基準 (PCI DSS)

PCI DSS(Payment Card Industry Data Security Standard) とは、クレジットカードの加盟店や決済代行事業者向けのセキュリティ基準であり、カード情報や取引情報を保護するための要件が既定されている。  
その中の1つはアクセスログについての要求となっています。下記参照してください。  

```TEXT
要件10：ネットワークリソースおよびカード会員データへの全てのアクセス追跡および監視する
```