Webとセキュリティの基礎学習メモ

# はじめに

こんにちは。takunと申します。

みなさんは「この一冊で全部わかるシリーズ」ご存じでしょうか。
この度とある案件参画の運びとなり、勧めていただいた本です。
- この一冊で全部わかるWeb技術の基本(2017/03/31初版第1刷)
- この一冊で全部わかるセキュリティの基本(2022/12/26初版第11刷)

上記の2冊を読み終えたので、個人的に学びをまとめていきます。
中古で買ったためやや古いですが、同じ初版なので内容は問題ないはず。
> 金欠エンジニアなので・・・

当方は初心者エンジニアです。間違ったことや不適切な内容となってしまう可能性もあることをご承知ください。また、助言など頂けると嬉しいです。


# RESTful
### RESTとは
REST(REpresentational State Transfer)はWebにおける設計思想の一つ。
このRESTに従って設計されたシステムを「RESTfulなシステム」と呼ぶ。

原則としては以下の4つ。
- 統一インターフェース
HTTPプロトコルのような共有された方法
- アドレス可能性
全てのURIがユニークである。
- 接続性
やりとりするデータにリンクを含めることができる。
- ステートレス性
前回の情報を持たない。1リクエスト1レスポンスの1往復で完結。

### WebAPI利用におけるRESTについて
RESTはWebAPIとのデータのやり取りにおいて、現在の主流。
これは扱うデータ形式の重さが問題で、XML-RPC,SOAPといったXMLを扱うプロトコルに比べて、RESTはJSONのような軽量なデータも利用できるのが強み。

> **WebAPIとは**
Webを通じてユーザーではなくプログラムが直接サービスを利用するための窓口を指す。
具体的には、
クライアントプログラムがWeb経由でAPIを提供するWebサービスにリクエストを送る。
↓
受け取ったWebサーバーがデータを処理し、再びWebを経由してクライアントに処理結果データを返す。
(例) GoogleマップAPI , Twitter投稿API等。

# Cookieとセッション
HTTPはステートレスなプロトコル。しかし、ショッピングサイトのカート機能等を実現するにはステートを維持しなければいけない。
それを実現する仕組みがCookieとセッション。それぞれの特徴は以下の通り。

### Cookie
- 接続してきたWebブラウザを識別するための情報のこと。HTTPの(ヘッダーフィールド)に記述される。
- ログイン等のリクエストに対し、サーバー側からCookie情報をレスポンス(Set-Cookie)。
Webブラウザは受け取ったCookieを保存しておき、リクエスト時に送信する(Cookie)。
- 有効期限(expires=date)を設定できる。
設定されていないCookieはWebブラウザが閉じられると同時に削除される。これを「セッションCookie」という。

### セッション
- ブラウザとサーバーのやり取りにおいて、一連の関連性のある処理の流れを指す。
- ブラウザを識別するための情報として「セッションID」をサーバーが生成・保存する。
これをCookieに含めてやり取りする。(ブラウザによってはCookieが使えないこともあり、URLやフォームに含む方法もある。しかし漏洩リスクが高い。)
- セッションIDと紐付けて買い物かごデータ等を保存する。

> Cookieとセッションの違いとしては、
-> 保持する場所：Cookieはブラウザ。セッションIDはサーバー。
-> 有効期限：Cookieは有効期限の調整ができるが、セッションはブラウザを閉じると情報が削除される。


# セキュリティの三要素と関連する問題
### 機密性 vs 情報漏洩
機密性 = 許可した人のみが情報に触れることができる。
例）個人情報漏洩事故。
機密性担保のために、暗号技術や認証技術が重要となる。

### 完全性 vs 改ざん
完全性 = 情報が本来想定した状態から改ざんされておらず、信頼に足る状態である。
例）企業のWebページの内容が書き換わる。
WebサイトのCMSのIDとパスワードが推測されてしまったり、使用しているソフトウェアの脆弱性を突かれることで起こる。

### 可用性 vs サービス妨害
可用性 = 情報にアクセスできる人は、いつでもその情報にアクセスできる。
例）サーバーダウンでサービス提供ができない。
脆弱性を突かれたり、外部からの要求が設計性能を超えることで起こる。

# 公開鍵暗号と共通鍵暗号
個人的にこのトピックはややこしいので、前提としてどの鍵が何に使われるのかを整理してみました。
### 使用用途と用いる鍵の組み合わせ
- 電子署名 -> 秘密鍵
- 電子署名を検証 -> 公開鍵
- データの暗号化 -> 公開鍵
- データの復号 -> 秘密鍵

### 電子署名とは
「電子データの作成者」を元のデータに付与し、データが改ざんされていないことを保証する。
手紙で言うシーリングスタンプ。重要書類へのサインのようなもの。
データの暗号化と比べややこしいので、以下署名〜検証の流れ。

【署名：送信者側】
- データのハッシュ値を算出
ハッシュ関数を使用して元のデータの固定長のハッシュ値を計算。このハッシュ値は、元のデータの内容を一意に表す固定長のバイナリデータ。
↓
- ハッシュの暗号化
計算したハッシュ値を自身の秘密鍵を使用して暗号化する。このプロセスにより、ハッシュ値が送信者の秘密鍵で署名され、電子署名が生成。

【検証：受信者側】
- 電子署名を復号、元データからハッシュ値取得
送信者の公開鍵を使用して電子署名を復号化し、ハッシュ値を取得。元のデータから再度ハッシュ値を計算。
↓
- 改めて自分でも計算しハッシュ値を比較
送信者の公開鍵で復号化した署名のハッシュ値と、再計算した元のデータのハッシュ値を比較。もし一致すれば、電子署名は有効。

> それぞれ使用する公開鍵や使用できるハッシュ関数については、3ウェイハンドシェイクで共有する。

### 共通鍵の必要性と運用
現在、共通鍵の暗号方式としてAESというアルゴリズムが推奨されている。AESの鍵の複雑さを表すために現状の解読技術で日数を算出すると、
```math
2^{128} = 2^{56}/日 × 1000京年
```
解読するのに地球滅びそう（笑）。そりゃ選ばれる。

しかし共通鍵暗号方式は暗号化・復号化を同じ鍵で行う。鍵がばれては折角の複雑さも意味がない。
よって、公開鍵暗号方式等で安全に共通鍵を共有するプロセスが重要となる。

# TLS/SSL
HTTPS通信を実現する技術としてTLS/SSLが用いられる。
TLS/SSLでは最初にハンドシェイクプロトコルを通して「相手が信頼できる相手なのか」を認証し、以下の要素を組み合わせてセキュアな通信を実現する。
- 3ウェイハンドシェイク（TLS Handshake）
クライアントHello:
クライアントがサーバーに接続を要求し、使用するTLS/SSLのバージョンや暗号スイートのリスト(暗号アルゴリズム、ハッシュ関数、鍵長)を伝える。
↓
サーバーHello:
サーバーは、クライアントに対して使用するTLS/SSLのバージョンや選択した暗号スイート、サーバー証明書（公開鍵と証明書情報を含む）を伝える。
↓
鍵交換:
サーバーが公開鍵を送信し、クライアントはその公開鍵を使用して共通鍵を暗号化してサーバーに送信します。この共通鍵は、通信の後続部分を暗号化するための共通の暗号鍵を生成するのに使用。
↓
Finishedメッセージ:
サーバーとクライアントは、それぞれが鍵交換から共通鍵を生成し、通信を暗号化する準備ができたことを示すFinishedメッセージを交換。安全な通信が確立。
- サーバー証明書の検証
クライアントは、サーバーから受け取った証明書が信頼できる認証局（CA）によって発行され、証明書が有効であることを確認。これにより、中間者攻撃やなりすまし攻撃から保護される。
- 公開鍵暗号方式と共通鍵暗号方式
前述の通り。

# VPNとHTTPSの違い
どちらもセキュアな通信を提供する目的で使用される。

異なる点としては、以下の通り。
- 目的
VPNは通常、組織の従業員や支社、パートナー企業がリモートアクセスを安全にできるよう使用される。
- 対象範囲
VPNはインターネットをはじめとした、ネットワーク通信全体(Webブラウジングだけでなくファイル転送、音声通話など)をカバーする。
HTTPSは特定のWebサービスに制限されたセキュリティを提供。
- プロトコル
VPNではSSLを用いたプロトコルの「SSTP」だけでなく、「IPsec」といったTCP/IP通信でパケット単位の暗号化を実現できるプロトコルも利用できる。

# 脆弱性と攻撃手法
脆弱性とは、「ある特定の攻撃に対して作成者が意図しない挙動をすること」を指す。

以下の攻撃手法があるため、運用前のシステムは特に脆弱性を洗い出す必要がある。
- ブルートフォース攻撃
パスワード総当たり攻撃
<font color="red"> <- </font>パスワードの文字数・文字種を十分に設ける。
- Dos/DDos
ボットを利用する等で集中アクセス攻撃
<font color="red"> <- </font>サーバーの負荷耐性・負荷分散、ボットへの感染防止。
- 中間者攻撃
あらゆる2者間通信の中間で通信の傍受・盗聴・改ざんする攻撃。典型的な方法は、中間に設置するプロキシサーバーを用意or乗っ取る。
<font color="red"> <- </font>攻撃者がデータを受け取っても見れないよう暗号化しておく。WebであればHTTPSを使用。
- バッファオーバーフロー
ソフトウェアへの入力を格納する領域を溢れさせる
<font color="red"> <- </font>入力データサイズチェック。シェルコードへの遷移に使われそうなアドレスをランダムにする。データ領域でのプログラム実行を禁止（あふれ領域での上書き禁止)。
- Webページ等の入力欄を利用した攻撃
<font color="red"> <- </font>基本的な対策としては、入力値をエスケープし無害とする。
  - SQLインジェクション
Webアプリへの入力を悪用、バックエンドのDBに不正操作をする。
<font color="red"> <- </font> パラメーターバインドの仕組みを利用したプログラムを構築する。</font>

  - OSコマンドインジェクション
OSコマンドの呼び出しに不正なパラメータを入力することで、シェルを不正操作する。

  - クロスサイトスクリプティング(XSS)
入力値を利用してWebページに不正なスクリプトを混入させる。不正なスクリプトが埋め込まれたWebページの利用者の個人情報が流出してしまう。

  - クロスサイトリクエストフォージェリ(CSRF)
認証情報を利用し、本人へなりすましてリクエストする。パスワード変更、決済、掲示板の書き込みなどアカウントを乗っ取る。 
<font color="red"> <- </font> 偽造されたリクエストを判別・検出する機能の実装
# おわりに
こんな新米エンジニアの記事をここまで見て頂けて嬉しいです。拙い文章で恐縮ですが、見ていただいてる方に分かりやすい内容となるよう努めていきます！
コメントやアドバイスなど頂けたら嬉しいです！