Webアプリケーション作成のための10ステップ　6. セキュリティ

# この記事を書いたきっかけ

この記事では、Webアプリケーションエンジニアに必要なスキルを具体的に解説し、その学び方を示します。

Webアプリケーション作成に必要なスキルを10個にまとめ、一つずつ学ぶ目的と手段を整理したいと思います。今回は**セキュリティ**について書きます。

### この記事を書いた目的
- webアプリケーションエンジニアになりたい
- そのために、自分に足りないものは何かを知りたい
- すぐに行動に移すために、学ぶ目的と手段を具体化したい
- webアプリケーションエンジニアに必要なスキルを全て把握したい
- 今、自分はなんのために、何を学んでいるのか、見失わないようにしたい


***
こちらの記事が大変参考になります

https://qiita.com/t_nakayama0714/items/83ac0b12ced9e7083927

# Webアプリケーション作成のための10ステップ
1. プログラミング言語の習得
1. フロントエンド開発
1. バックエンド開発
1. バージョン管理
1. 開発ツールと環境
1. セキュリティ
1. デプロイメントとクラウド
1. テスト
1. アーキテクチャの知識
1. ソフトスキル

# 6. セキュリティ
# セキュリティとは何か（What）
セキュリティとは、不正アクセスやデータ漏洩、その他の攻撃から、Webアプリケーションやそのデータを守ることを指します。具体的には、ユーザーの認証と認可、データの暗号化、脆弱性の管理などを行います。Webアプリケーションのセキュリティをしっかり行うことで、ユーザーからの信頼を維持することができます。

### 主なセキュリティ技術
- **認証と認可**：ユーザーが誰であるかを確認し、アクセス権を管理する技術。
- **データ暗号化**：データの盗聴や改ざんを防ぐために、データを暗号化する技術。
- **脆弱性管理**：セキュリティホールや脆弱性を検出し、修正するプロセス。
- **セキュリティヘッダー**：HTTPレスポンスヘッダーを使って、Webアプリケーションのセキュリティを強化する技術。
- **インプットバリデーション**：ユーザー入力を検証し、SQLインジェクションやクロスサイトスクリプティング（XSS）などの攻撃を防ぐ技術。

下記で詳しく説明します。

# なぜセキュリティ対策をしなければならないのか（Why）
### 1. データの保護
セキュリティの知識がないと、ユーザーの個人情報や機密データが漏洩するリスクが高まります。データ漏洩は、個人のプライバシー侵害や企業の信頼失墜につながります。

### 2. 法的遵守
多くの国や地域では、個人情報保護法やデータセキュリティ法が制定されており、これら法律を守ることが求められます。セキュリティの知識がなければ、法令遵守が難しくなり、罰則や訴訟のリスクが増大します。

### 3. システムの信頼性向上
セキュリティ対策を講じることで、システムの信頼性と可用性が向上します。攻撃によるダウンタイムやシステム障害を防ぎ、ユーザーに安心してサービスを利用してもらうことができます。

### 4. 経済的損失の防止
セキュリティ侵害が発生すると、対応コスト、信頼回復のためのマーケティングコスト、法的費用などが発生します。セキュリティ対策を事前に行うことで、これらの経済的損失を防ぐことができます。

### 5. 競争力の維持
セキュリティを重視する企業は、顧客やパートナーから信頼され、競争力を維持することができます。セキュリティの欠如は、競争優位性を失う原因となります。

## セキュリティ対策をしなかったらどうなるのか

### データが漏洩してしまう
セキュリティの知識がないと、SQLインジェクションやクロスサイトスクリプティング（XSS）などの基本的な攻撃からデータを保護できません。ユーザー情報や企業の機密情報が漏洩してしまうと、システムだけでなく会社そのものの信頼性が損なわれます。一度信用を失うと、なかなか回復しません。

### 経済的損失
セキュリティ侵害が発生すると、復旧や対策にかかるコストが増大します。また、上記のように顧客やビジネスパートナーからの信頼を失ったことによる顧客離れや売上の減少も考えられます。競合他社が適切なセキュリティ対策を講じている場合、競争力が著しく低下します。

### サイバー攻撃のリスク増大
適切なセキュリティ対策が施されていないシステムは、サイバー攻撃の標的となりやすくなります。古いシステムを使っていたり、サポートが終了しているサービスを使い続けてしまうと、サイバー攻撃を受けるリスクが高くなります。結果的に、サービス停止やデータの改ざんなどの被害が発生します。

### 開発の遅延と効率低下
セキュリティに関する基本的な知識がないと、開発中に発生するセキュリティ問題の対応に追われ、プロジェクトの進行が遅れることがあります。開発効率が低下し、リリースが遅れてしまいます。


# 具体的にどんなセキュリティを施せばいいのか（How）
## 認証と認可
### 認証と認可とは何か
**認証**とは、ユーザーが誰であるかを確認するプロセスです。一般的には、ユーザー名とパスワード、あるいは多要素認証（MFA）を用います。
**認可**は、認証されたユーザーがどのリソースにアクセスできるかを制御するプロセスです。

### なぜ認証と認可が必要なのか
認証によって不正アクセスを防ぎ、認可によってユーザーごとに適切な権限を付与することで、機密情報の漏洩や不正操作を防ぐことができるからです。ユーザーを正しく識別するプロセスと、ユーザーごとにできること（権限）を分けるプロセスによって、安全なWebアプリケーションを維持することができます。

### 具体的なツールと技術
**OAuth**：ユーザーの認証情報を共有せずに、他のアプリケーションやサービスに対してアクセス権を委譲するプロトコル。例：FacebookやGoogleのアカウントを使って他のウェブサイトにログインする。

**OpenID Connect**：OAuth 2.0を基にした認証プロトコル。ユーザーの身元確認を行います。例：Googleでサインイン。

**JWT（JSON Web Tokens）**：認証情報を安全に伝達するためのトークン形式。自己完結型で、改ざん防止の署名が含まれています。例：ウェブアプリがユーザーのログイン状態を保持するために使用。
## データ暗号化
### データ暗号化とは何か
データ暗号化とは、データを読み取れない形式に変換し、許可された者だけが解読できるようにする技術です。データが盗聴や改ざんから保護するために暗号化します。

### なぜデータ暗号化が必要なのか
通信中や保存中のデータが第三者によって不正にアクセスされるのを防ぐことができれば、データを盗聴されたり改ざんされることはなくなります。無用なトラブルを回避できます。

### 具体的なツールと技術
**SSL/TLS**：SSL（Secure Sockets Layer）とTLS（Transport Layer Security）は、インターネット上での安全な通信を確保するためのプロトコルです。例：HTTPSによるウェブサイトの暗号化通信。

**AES（Advanced Encryption Standard）**：AES（Advanced Encryption Standard）は、データを暗号化するための共通鍵暗号化の標準です。共通鍵暗号化とは、暗号化と復号に同じ鍵を使用する方式です。例：企業のデータベース暗号化。

**RSA**：公開鍵暗号化の標準。公開鍵暗号化の標準です。公開鍵暗号化とは、暗号化と復号に異なる鍵を使用する方式で、公開鍵と秘密鍵のペアが使われます。公開鍵は誰でも知ることができますが、秘密鍵を知っているのは所有者だけです。例：オンラインバンキングでの安全なデータ送信。

## 脆弱性管理
### 脆弱性管理とは何か
脆弱性管理は、ソフトウェアのセキュリティの脆弱性を検出し、修正するプロセスです。脆弱性管理を行うことで、攻撃者がシステムを悪用するのを防ぎます。

### なぜ脆弱性管理が必要なのか
脆弱性を放置すると、攻撃者によってシステムが侵害されるリスクが高まります。

### 具体的なツールと技術
**OWASP ZAP（オワスプ・ザップ）**：オープンソースの脆弱性診断ツールです。Webアプリケーションの脆弱性を検出し、開発中にセキュリティ問題を修正するのに役立ちます。

**Nessus（ネサス）**：商用の脆弱性検知スキャナーです。ネットワークやシステムの包括的なセキュリティスキャンを行い、詳細なレポートを提供します。

**Snyk（スニーク）**：依存関係の脆弱性を管理するツールです。オープンソースライブラリの脆弱性を検出し、修正の提案を行います。
## セキュリティヘッダー
### セキュリティヘッダーとは何か
セキュリティヘッダーは、HTTPレスポンスヘッダーを使って、Webアプリケーションのセキュリティを強化する技術です。ブラウザの動作を制御し、攻撃を防ぎ目的があります。

### なぜセキュリティヘッダーが必要なのか
セキュリティヘッダーは、セキュリティヘッダーは、悪意のある攻撃からWebサイトとそのユーザーを守るために重要です。
例えば、以下のような攻撃を防ぐことができます。
- **クロスサイトスクリプティング（XSS）**：悪意のあるコードがWebページに挿入され、ユーザーがそのコードを実行してしまう攻撃。
- **クリックジャッキング**：ユーザーに見えないボタンやリンクをクリックさせて、不正な操作を行わせる攻撃。
- **MIMEスニッフィング**：ブラウザがファイルの種類を誤って判断し、意図しない動作をさせる攻撃。


### 具体的なツールと技術
**Content-Security-Policy（CSP）**：Webページが読み込むことができるリソース（例えばスクリプト、スタイルシート、画像など）を制御する設定です。信頼できるリソースのみが読み込まれるようにし、悪意のあるコードの挿入を防ぎます。クロスサイトスクリプティング（XSS）やデータインジェクション攻撃の防止に効果的です。

**Strict-Transport-Security（HSTS）**：ブラウザに対して、自分のサイトには必ず安全な接続（HTTPS）でアクセスするように指示します。HTTP接続だった場合、強制的にHTTPS接続に変更します。通信が暗号化されるので、安全性が高まります。

**X-Content-Type-Options**：ブラウザに対して、サーバーが指定したファイルの種類（MIMEタイプ）を信頼するように指示します。その結果、ブラウザがファイルの種類を誤って判断するのを防ぐことができます。上記のMIMEスニッフィング攻撃を防ぐ目的があります。

## インプットバリデーション
### インプットバリデーションとは何か
インプットバリデーションとは、ユーザーからの入力データを検証し、不正なデータや攻撃を防ぐための技術です。具体的には、入力されたデータが期待される形式や範囲内にあるかどうかを確認します。システムに悪影響を及ぼす可能性のあるデータが処理されるのを防ぐ目的があります。

### なぜインプットバリデーションが必要なのか
**インプットバリデーションの目的**
- **SQLインジェクションの防止**：攻撃者が入力フィールドを通じて悪意のあるSQLクエリを挿入し、データベースを不正操作する攻撃を防ぎます。
- **クロスサイトスクリプティング（XSS）の防止**：攻撃者が悪意のあるスクリプトを入力し、それが他のユーザーのブラウザで実行されるのを防ぎます。
- **データの整合性確保**：入力されたデータが期待される形式や値であることを確認し、システムが適切に動作するようにします。

### 具体的なツールと技術
**正規表現**：正規表現（Regular Expressions）は、入力データの形式を検証するためのパターンマッチング技術です。特定の文字列パターンに一致するかどうかを確認するのに使用されます。

#### 正規表現の具体例
```js
// JavaScript
// メールアドレスの検証
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const isValidEmail = emailPattern.test(userInput);

// 電話番号の検証
const phonePattern = /^\d{3}-\d{3}-\d{4}$/;
const isValidPhone = phonePattern.test(userInput);
```
**ライブラリ**：各プログラミング言語には、インプットバリデーションを簡単に行うためのライブラリが用意されています。これらのライブラリは、入力データの検証を効率的かつ確実に行うための機能を提供します。

#### ライブラリの具体例
**DjangoのFormバリデーション**：Djangoフレームワークでは、フォームバリデーション機能が組み込まれており、ユーザー入力を簡単に検証できます。
例：Python用ライブラリ
```python
from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if not email.endswith('@example.com'):
            raise forms.ValidationError('Invalid email domain')
        return email
```
# どのように学習すればいいのか（How）
**書籍**：書籍『[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践](https://www.amazon.co.jp/%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6-%E5%AE%89%E5%85%A8%E3%81%AAWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E7%AC%AC2%E7%89%88-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%8C%E7%94%9F%E3%81%BE%E3%82%8C%E3%82%8B%E5%8E%9F%E7%90%86%E3%81%A8%E5%AF%BE%E7%AD%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E5%BE%B3%E4%B8%B8/dp/4797393165)』を読んでみると、大変参考になると思います。Webアプリケーションにおけるセキュリティの基礎知識を体系的に学ぶことができます（まだ少ししか読んでいませんがおすすめです）。

**資格**：基本情報技術者試験や応用情報技術者試験では、セキュリティに関する問題が出題されます。特に、応用情報技術者試験では午後問題の回答必須項目となっています。他には、情報セキュリティマネジメント試験や情報処理安全確保支援士試験があります。
参考HP：[IPA 試験情報トップページ](https://www.ipa.go.jp/shiken/index.html)

**動画**：Udemyなどでセキュリティに関する動画を視聴するとわかりやすいです。paizaでは「[「Webセキュリティ」入門編](https://paiza.jp/works/search_courses/2122)」という講座があります。

**実践**：実際にWebアプリを作成すれば、必然的にセキュリティ対策をすることになります。そこから、少しずつセキュリティの知識を身につけていくことができます。

# 実際に勉強したこと（Try）
- **書籍**：『[図解まるわかり セキュリティのしくみ](https://www.amazon.co.jp/%E5%9B%B3%E8%A7%A3%E3%81%BE%E3%82%8B%E3%82%8F%E3%81%8B%E3%82%8A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E5%A2%97%E4%BA%95-%E6%95%8F%E5%85%8B/dp/4798157201)』を読みました。
- **資格**：基本情報技術者試験の勉強をして資格を取りました。応用情報技術者試験の午後問題対策のために、セキュリティの理解には力を入れています。
    - [情報セキュリティマネジメント試験　過去問道場](https://www.sg-siken.com/sgkakomon.php)の問題を解いたり、このHP内の情報セキュリティマネジメント用語辞典を活用して勉強しました。
- **動画**：Udemyの動画で勉強しました。
    - 「[令和6年版:参考書の著者直伝！【基本情報技術者試験　科目A】講座　基礎理論から経営戦略までの全範囲を網羅](https://www.udemy.com/course/kihon_joho/?couponCode=KEEPLEARNING)」
    - 「[令和６年秋版：参考書の著者直伝！【応用情報技術者試験　午前版】講座 　合格に必要な知識の徹底解説＋過去問題解説](https://www.udemy.com/course/ouyou_joho/?couponCode=KEEPLEARNING)」
- **実践**：Djangoフレームワークを使用してWebアプリケーションを作成し、その際にフォームバリデーションやCSRF対策、HSTS設定を実施しました。

# まとめ
Webアプリを作成する以上、ユーザーには安全に楽しく使っていただきたいものです。そのためには、安心して使ってもらえるように、セキュリティ対策はちゃんとしておきたいです。

ただ、一口にセキュリティ対策といっても本当に幅広く、数も多く、しかも攻撃手法は日々変化しています。すぐにセキュリティ全般を理解することはできませんが、身近なところから少しずつ勉強していこうと思います。