HTTPとセッション管理

こちらの記事は以下の書籍を参考に執筆しました

[体系的に学ぶ 安全な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%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%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-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)


#なぜHTTPを学ぶのか
WEBアプリケーションの脆弱性にはWEB固有の特性に由来する物があり、これを理解するためにHTTPやセッション管理について理解しておくべきだから。

#GETとPOSTの使い分け
GETの場合は以下の危険性がある。

- URL上に指定されたパラメータがReferer経由で外部に漏洩する
- URL上に指定されたパラメータがアクセスログに残る
- URL上のパラメータがブラウザのアドレスバーに表示された人にのぞかれる
- パラメータつきのURLを利用者がソーシャルネットワークなどで共有してしまう

以下のの項目に1つでも当てはまる場合は**POST**
1つも当てはまらない場合は**GET**

- データ更新など副作用を伴うリクエストの場合
- 秘密情報を送信する場合
- 送信するデータの送料が多い場合

#hiddenパラメータのメリット
hiddenパラメータは利用者自身が書き換えが可能だが、**情報漏洩や、第三者側からの書き換えに対しては堅牢**

利用者自身によって書き換えられては困るものはセッション変数に保存し、それ以外はheddenパラメータに保存することを検討すべき。

特に、ログイン前では、認証、認可に関する情報はないので、原則セッション変数の使用を避け、hiddenパラメータを使用することが情報漏洩などに対して安全である。


#認証
HTTPには認証機能がサポートされている。
実装方式により以下の種類がある。

- Basic認証
- NTML認証
- Digest認証

##Basic認証
認証が必要なページにリスクエスト場あるといったん
`401 Unauthorized`(認証が必要なのにされていない)というステータスを返す。

ブラウザはこれを受けてID、パスワードの入力画面を出し、入力されたIDとパスワードを追加したリクエストをサーバーに送信する。

以下はPHPでのBasic認証の例

```php5
<?php
$accounts = [
    'user1' => 'pass1',
    'user2' => 'pass2',
    'user3' => 'pass3',
];
  $user = @$_SERVER['PHP_AUTH_USER'];
  $pass = @$_SERVER['PHP_AUTH_PW'];
  if (! $user || ! $pass ||
    !(isset($accounts[$user]) && $accounts[$user] === $pass) ) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="Basic Authentication Sample"');
    echo "ユーザ名とパスワードが必要です";
    exit;
  }
?>
<body>
認証しました<BR>
ユーザ名:<?php echo htmlspecialchars($user, ENT_NOQUOTES, 'UTF-8'); ?><BR>
パスワード:<?php echo htmlspecialchars($pass, ENT_NOQUOTES, 'UTF-8'); ?> <BR>
</body>
```
>出典：[体系的に学ぶ 安全な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%EF%BC%BB%E3%83%AA%E3%83%95%E3%83%AD%E3%83%BC%E7%89%88%EF%BC%BD-%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-%E6%B5%A9-ebook/dp/B07HHT54YR/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%81%82%E3%81%B7%E3%82%8A&qid=1595990262&s=digital-text&sr=1-2)

`$user`,`$pass`にいずれかがセットされていない場合、ブラウザに`401`を返す。

ブラウザ側でIDとパスワードを入力し再度リクエストすると、リクエストヘッダに、以下のような`Authorization`ヘッダが付与される。

```
Authorization: Basic [Base64エンコード]
```
「Basic」の後ろのコードはIDとパスワードを「：」で区切り`Base64`エンコードしたもの。
これをBase64でデコードすればもとのIDとパスワードが見れる。

###Basic認証には「ログアウト」がない
Basic認証は一度認証されるとその後はずっと`Authorization`ヘッダが付与されるため、認証状態が保存されているように見えるが、`Authorization`ヘッダが付与されているということは、いちいちIDとパスワードを送信しているということで、認証状態は保存されていない。

**つまりBasic認証もステートレスであり、ログアウトという概念がない。**