Open1
ウェブ・セキュリティ基礎試験(徳丸基礎試験)⑧
徳丸基礎試験勉強まとめ⑧
「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」の4章の4.15 ~ 4.17を自分なりにまとめる
アドバイスや間違い指摘など歓迎です
4章 「Webアプリケーションの機能別に見るセキュリティバグ」
4.15 共有資源やキャッシュに関する問題が原因でなにが起こるの?
- 共有資源に関する問題 => 競合状態の脆弱性
- 別人の個人情報が表示される
- データベースの不整合
- ファイル内容の破壊
- キャッシュに関する問題 =>キャッシュからの情報漏洩
- 他のユーザーの情報が表示される
競合状態の脆弱性の対策は?
- 共有資源を使用しない
- 排他制御を行う
キャッシュからの情報漏洩の対策は?
-
構成
- ユーザーリクエスト => キャッシュサーバーリクエスト => アプリケーションサーバーレスポンス => キャッシュサーバーレスポンス
-
アプリケーション側でキャッシュ制御用の適切なレスポンスヘッダを設定する
- Cache-controlヘッダの設定
- no-store: 全くキャッシュなし
- no-cache: キャッシュ有効性を毎回サーバーに確認
- private: 1人のユーザーのためのキャッシュ許可。(ブラウザキャッシュ許可、キャッシュサーバーキャッシュ禁止)
- public: 全てのキャッシュ保存許可
- must-revalidate: キャッシュが陳腐化していないか確認
- max-age: リソースが陳腐化していないと考えられる最長期間(秒)
- Cache-controlヘッダの設定
-
キャッシュサーバー側でキャッシュ制御の適切な設定を行う
- 例えばnginxの場合、proxy_ignore_headerの設定を確認
- proxy_ignore_headerにCache-controlを設定していると、アプリケーション側でCache-controlヘッダをレスポンスしても無視されてしまう
- 例えばnginxの場合、proxy_ignore_headerの設定を確認
-
キャッシュバスターを実施する(URLのクエリに乱数ちを付与する)ことでキャッシュを使用しないようにする
4.16 Web API実装における脆弱性
JSONとJSONPとは
- JSON
- Ajaxで使用されるデータ交換形式(元々はJSONの代わりにXMLを使用していた)
- JSONP
- XMLHttpRequestではなくscript要素を用いて外部JSを直接実行してデータ取得
- CORSができる前に、異なるオリジンのサーバーとやり取りするために開発された(同一オリジンポリシーの枠内でデータやり取り)
Web API実装における脆弱性が原因でなにが起こるの?
- JSONエスケープの不備
- JSON直接閲覧によるXSS
- JSONPのコールバック関数によるXSS
- WebAPIのCSRF
- JSONハイジャック
- JSONPの不適切な利用
- CORSの検証不備
- セキュリティを強化するレスポンスヘッダ
- X-Frame-Options: frameやiframeの内部に表示することを禁止
- X-content-Type-Options: MIMEタイプを厳密に指定(nosniffにする)
- X-XSS-protection: XSSフィルタの設定をブラウザでしていても、フィルタの動作モードを上書きする(X-XSS-protection: 1; mode=block)
- Content-Security-Policy: https://techblog.securesky-tech.com/entry/2020/05/21/
- Strict-Transport-Security: HTTPSを強制する
JSONエスケープの不備の対策は?
- 信頼できるライブラリを用いてJSONを生成(' { "error": "エラー内容: ' . $error . ' "}' などの文字列連携でJSONを生成しないこと!script要素として展開された場合、XSS攻撃される危険がある)
- eval関数ではなくJSON.parseなどの安全なAPIでJSONを解釈
- JSONPを避け、CORSを用いたWeb APIに移行
JSON直接閲覧によるXSSの対策は?
- MIMEタイプを正しく設定する
- JSONのMIMEタイプはapplication/jsonなので、content-typeレスポンスヘッダをapplication/jsonに設定
- 直接閲覧されるとHTMLとして解釈されるが、content-typeレスポンスヘッダをapplication/jsonに設定すればHTMLとして解釈されなくなる
- X-content-type-optionsレスポンスヘッダをnosniffを出力する
- 古いタイプのIEだと、MIMEタイプではなく、拡張子を元にMIMEタイプを判断してしまう
- X-content-type-options: nosniffでIE8, IE9はMIMEタイプをもとに判断するようになる
- ただし、IE7では効果なし
- 以下、IE7でもなるべく安全にするための対策
- 大なり小なり記号など、HTMLに解釈される恐れのある記号をUnicodeエスケープする
- X-Requested-Withリクエストヘッダをチェックし、XMLHttpRequestなどCORS対応機能以外からのリクエストを受け付けないようにする(直接閲覧不可にする)
- X-Requested-With: XMLHttpRequestリクエストヘッダなどをチェック
JSONPのコールバック関数によるXSSの対策は?
- MIMEタイプを正しく設定する
- JSONPのMIMEタイプはtext/javascriptなので、content-typeレスポンスヘッダをtext/javascriptに設定
- これで、HTMLとして解釈されなくなるので、スクリプト要素は解釈されず、JSの実行がなくなる
- コールバック関数名の文字種と文字列を制限する
- 英数字とアンダースコアのみに制限するなど
- これで、スクリプト(<script>alert(document.cookie)<script>など)をコールバック関数として挿入されなくなる
WebAPIのCSRFの対策は?
-
重要な処理はGETでは行わない
-
CSRFトークン
- ログイン時にサーバーでトークン生成
- フロントにトークン送信
- フロントはX-CSRF-TOKENリクエストヘッダにトークンを指定(X-CSRF-TOKENヘッダを使用するためには、プリフライトリクエストが必要。シンプルなリクエストの条件外のため)
- サーバーはトークンが正しいか確認して処理実行
- つまり、CSRFトークンを使用すると、プリフライトリクエスト&トークン確認で多重チェックされる
-
二重送信クッキー
- トークンをクッキーとして保存+同じトークンをX-CSRF-TOKENリクエストヘッダに指定
-
カスタムリクエストヘッダ
- X-Requested-Withリクエストヘッダをチェックし、XMLHttpRequestなどCORS対応機能以外からのリクエストを受け付けないようにする
- X-Requested-With: XMLHttpRequestリクエストヘッダなどをチェック
- X-Requested-Withリクエストヘッダをチェックし、XMLHttpRequestなどCORS対応機能以外からのリクエストを受け付けないようにする
-
入力データのMIMEタイプを検証する
- プリフライトリクエストの必要ないシンプルなリクエストの場合でも、サーバー側でPOSTデータの中身を確認すること!Content-typeリクエストヘッダで指定してあるMIMEタイプと、実際にPOSTデータ内で送られているタイプが違うことが可能(シンプルなリクエストでもJSON形式データを送れる)
- シンプルなリクエストの場合、クロスオリジンの許可をしていない場合でも、クロスオリジンからリクエストを送信することはできてしまう(CSRF可能)
-
CORSを適切に実装する
- Access-Control-Allow-Origin: * でどんなオリジンでも許可にしてしまうなどはNG!!
JSONハイジャックの対策は?
-
JSONハイジャック
- scriptのsrcにhttp://example.com/test.jsonなどjsonやcsv形式の値を指定して読み取る
-
X-content-type-optionsレスポンスヘッダをnosniffを出力する
- scriptタグでapplication/jsonのコンテンツを読み込めないようになる(一部Firefoxでは読み取れる場合も。)
-
X-Requested-Withリクエストヘッダをチェックし、XMLHttpRequest経由以外からのリクエストを受け付けないようにする
- scriptタグではカスタムヘッダ送信できないため、scriptから呼び出されても処理を行わないようにできる
JSONPの不適切な利用の対策は?
- X-Requested-Withリクエストヘッダをチェックし、XMLHttpRequest経由以外からのリクエストを受け付けないようにする(JSONPの使用をやめる)
CORSの検証不備の対策は?
- CORSのヘッダを正しく設定する
- Access-Control-Allow-Origin: * でどんなオリジンでも許可にしてしまうなどはNG!!
4.17 JavaScriptの問題
JavaScriptの問題が原因でなにが起こるの?
- DOM-based XSS
- innerHTMLやdocument.write, JQueryセレクタの動的生成, javascriptスキーム(location.href, a要素やiframe要素など) でScript実行
- URLパラメータやlocation.hashからの外部入力, XML HttpRequestのURL未検証(外部URLへリクエスト)により攻撃用スクリプトが混入
- Webストレージの不適切な使用
- クッキー、LocalStorage(ブラウザ内共通、有効期限無制限), SessionStorage(タブごと、有効期限タブを閉じるまで)
- PostMessageの呼び出しの不備
- PostMessageは異なるオリジン間でメッセージを送受信する仕組み
- オープンリダイレクト
DOM-based XSSの対策は?
- 適切なDOM操作あるいは記号のエスケープ
- innerHTMLプロパティをtextContentプロパティに置き換え
- document.writeの使用をやめるか、入力をエスケープしてからdocument.writeを使用
- eval, setTimeout, Functionコンストラクタなどの引数にStringで外部入力を渡さない
- URLのスキームをhttpかhttpsに限定する(url形式か確認し、スクリプトが入力されないようにする)
- JQueryの引数は動的生成しない、またはJQueryの最新ライブラリを使用する
- XML HttpRequestのURLを確認する
Webストレージの不適切な使用の対策は?
- 重要な情報はWebストレージには保存せず、サーバーに毎回問い合わせる
PostMessageの呼び出しの不備の対策は?
- postMessageメソッドの第二引数で送信先オリジンを確認
- onMessageイベントハンドラにて、event.origin(送信元オリジン)を確認
オープンリダイレクトの不備の対策は?
- location.hrefなどで指定するリダイレクト先URLを固定する
- ダイレクト先URLを直接指定せず、番号などで指定する