Closed34

「フロントエンド開発のためのセキュリティ入門」(スライド)を見る

hajimismhajimism

リスクその1:暗号化の失敗

通信データの暗号化によって対策する。

hajimismhajimism

HTTPにはいくつかのセキュリティ上の弱点がある

hajimismhajimism

通信相手の手がかりがURLしかないので、なりすましに弱い

hajimismhajimism

通信途中で攻撃者による改ざんがあっても検知できない

hajimismhajimism

そこでHTTP通信の前に暗号化通信を確立したやり方がHTTPS

暗号化通信の確立の大まかな流れは

  1. 暗号アルゴリズムなどの決定
  2. サーバー認証
  3. 鍵交換
  4. 共通鍵を使った暗号通信の開始&ハンドシェイクの改ざんチェック

ハンドシェイクってよく見るけど雰囲気でしかわかってない

hajimismhajimism

通信データの暗号化にはTLSというプロトコルを用いる。公開鍵を使って暗号化した共通鍵を使って文書を暗号化・復号する。

hajimismhajimism

通信相手の検証には照明局が発行した電子証明書を用いる。
ブラウザにはもともとルート証明書と呼ばれる、信頼できる証明書が組み込まれているらしい。

このため、Webブラウザなど公開鍵暗号を利用するソフトウェアの開発者は、世界的に有力な大手の商用認証局や政府機関の認証局など、信頼するに足ると思う機関が自ら発行する証明書を事前に入手して組み込んでおき、証明書を上位にたどっていった結果その機関の証明書に行き当たったら正しく検証されたと判断するようにしている。

この信用の連鎖により安全に公開鍵暗号を運用する社会的な基盤のことをPKI(Public Key Infrastructure/公開鍵基盤)と呼び、その最上位に位置する機関をルート認証局(ルートCA)、その発行する自らのデジタル証明書をルート証明書という。(出典

hajimismhajimism

昨今、HTTPSはほぼ必須。HTTPSでしか使えないAPIもある。

hajimismhajimism

HTTPS化するためにすること

  • Mixed Contentの修正
  • HTTP→HTTPSのリダイレクト設定
  • HSTSの設定
hajimismhajimism

Mixed Contentの修正

HTMLがHTTPSで配信されていても、サブリソースのJSがHTTPで配信されてしまっているなど、HTTPで配信されているリソースとHTTPSで配信されているリソースが混在する状態があり得る。

サブリソースでもHTTPで配信されていたらそこから潜り込まれる危険性がある

hajimismhajimism

HTTP→HTTPSのリダイレクト設定

もろもろの都合でHTTPがやめられないときもある。そういうときのために、サーバー側でHTTPのリクエストをすべてHTTPSへリダイレクトする設定を行う。

hajimismhajimism

HSTSの設定

HTTP Strict Transport Securityはブラウザから送信されるリクエストをすべてHTTPSに強制できる機能。

Strict-Transport-Securityヘッダを受け取ったブラウザは、次回以降のリクエストをHTTPS通信で行うようになる。

Strict-Transport-Security:includeSubdomainsでサブドメインにも適用可

hajimismhajimism

HTST Preloadリストとやらにホスト名が登録されていれば、自動的にHTTPSにしてくれるらしい

hajimismhajimism

リスクその2:アクセス制御の不備

CORSを使ったアクセス制御により対策する

hajimismhajimism

ブラウザには外部のアクセスを制限するOrigin(スキーム名+ホスト名+ポート番号)という境界線がある

hajimismhajimism

Originが同一であることをSame Origin、異なることをCross Originと表現する

hajimismhajimism

ブラウザは一部のデータのやり取りをSame Originにだけ許可している。ざっくりいうとこれがSame Origin Policy。これによりCross Originへの種々のリクエストが制御される。

hajimismhajimism

Cross Origin Resource Sharingを設定すればfetchなどを使ったデータのやり取りが可能になる。

hajimismhajimism

クロスオリジンのサーバーからのレスポンス自体はいつも返ってくるらしい。CORSヘッダを見てブラウザがデータの取り出し許可を出すかどうか決める。

hajimismhajimism

CORSではリクエスト自体は防げないので、データの更新や削除など副作用のあるリクエストを対策するには工夫が必要。

それがプリフライトリクエスト。事前に「このメソッド問題ないですか?」と聞きに行く。

hajimismhajimism

リスクその3:インジェクション
XSSの対策をする

hajimismhajimism

XSSにもいろいろ種類があるらしい

hajimismhajimism

反射型XSS
悪意のあるリンクを踏むとレスポンスによって反応的に被害を受ける?

hajimismhajimism

蓄積型XSS
サーバーへ送信された不正スクリプトをDBなどに保存してしまうことで半永続的な被害を受ける

hajimismhajimism

DoM-based XSS これが本題っぽい

DOM操作が脆弱性の原因となるもので、サーバーを介さずに攻撃が成立するため検知が難しい。
Dev toolのおかげでフロントエンドの脆弱性は見つけやすい。

hajimismhajimism

文字列のエスケープ処理を挟むことで悪意のあるスクリプトを実行してしまうことは大抵防げる。
Reactなどの有名ライブラリ・フレームワークはそこらへんのことをすでにやってくれている。
ただしdangerouslySetInnerHTMLのように脆弱なAPIが一部存在する。

hajimismhajimism

<a href='javascript:void(0)' >Help me!</a>みたいに、javasript:スキームのURLがあるとそこからスクリプトを実行できてしまう。https:などから始まるURLに絞り込むべき。

hajimismhajimism

Linkコンポーネントの実装例

const Link  = ( props ) => {
  const protocol = new URL(props.href).protocol
  const safeUrl = /^https:/.test(protocol) ? props.href : ""

  return <a href={safeUrl}>{props.children}</a>
}
hajimismhajimism

DOMPurifyライブラリやSanitizer APIなどでサニタイズができるらしい

hajimismhajimism

またContent Security Policyとやらで許可されていないリソースの読み込みをブロックすることができるらしい。
フロントエンドだけでも設定できるが、運用途中からの導入は難しい。

hajimismhajimism

リスクその4:古くなったコンポーネント

npm audit fixやDependabotで対策する

このスクラップは2023/02/16にクローズされました