安全なWebアプリケーションの作り方1
読書会でのメモ
HTTPとセッション, 同一生成元ポリシー
HTTP
- クライアントからサーバへのリクエスト、サーバからクライアントへのレスポンスで構成されるプロトコル
- リクエストラインの構成は以下
- メソッド
- リクエストURL
- プロトコルバージョン
- 実際には
GET /hoge.php HTTP/1.1
といった形式となる - リクエストヘッダにはRefererなどがつく
- Refererはアプリケーションが意図した遷移を経ているかをサーバ側で検証する場合などに用いられるが、改変が容易
- URLにセッションIDなど機密情報が含まれる場合にはセキュリティリスクとなる
- レスポンスメッセージの構成は以下
- ステータスライン
HTTP/1.1 200 OK
- ヘッダ
Date: foo Server: Apache/2.2.14...
- 空行
- 本体
<body>...
- レスポンスヘッダはContent-lengthやContent-Typeなどが代表的
- Content-TypeはMIMEタイプというリソースの種類を指定するhtmlであれば
text/html
, jpg画像であればimage/jpg
, pdf文書であればapplication/pdf
- 特殊記号や日本語などのマルチバイト文字列をURL上に記述する場合はパーセントエンコーディングを行う必要がある
- GET/POSTについて
- GETメソッドを用いる場合は、「リソースに対して副作用を起こさない・機密情報を送信しない・送信するデータ量が少ない」場合に用いるのが望ましい
- Referer経由で情報が漏洩する・アクセスログに記録されるため
- hiddenパラメータは書き換え可能
- HTTPには認識機構が用意されている
- Basic認証
- Digest認証
$user = $_SERVER['PHP_AUTH_USER']; $pass = $_SERVER['PHP_AUTH_PW']; if (!$user || !$pass) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Basic realm="Basic Authentification Sample"'); exit; }
- Basic認証が設定されているサーバから401のレスポンスを受け取ると、ブラウザはBasic認証のidとpassを受け取るダイアログを表示する
- 認証に成功すると、ブラウザはリクエストヘッダにAuthentificationを付与して送信し、ページの閲覧が可能となる
- Cookieとセッション管理
- HTTPはステートレスなプロトコルであるが、クライアント・サーバ間でログイン状態やその他の情報を記憶しておきたい場面が存在する
- 認証状態の管理はセッション管理と呼ばれ、HTTPではブラウザのCookieを用いて実現される
- 有効期限の設定されていないCookieはSessionと呼ばれ、ブラウザが閉じられるまで有効となる
- Cookieは文字列長および利用者による変更が可能なため、Cookieにはセッションidのみ記録し、実際のセッション管理を行う値はサーバ側で保持することが多い
- セッションidに求められる要件は以下
- 第三者がセッションidを推測できない
- 第三者からセッションidを強制されない
- 第三者にセッションidが漏洩しない
- 上記を満たすため、セッションには以下のようなことを考慮する必要がある
- 乱数の質
- ネットワーク的な盗聴の危険性
- XSSからの漏洩
- CookieのDomain属性/Secure属性/HttpOnly属性
- Referer