JSホモロジー戦略とCSRFの詳細な説明

JSホモロジー戦略とCSRFの詳細な説明

概要

この記事には主に 3 つのキーワードが含まれています。

  • 同一生成元ポリシー (SOP)
  • クロスサイトリクエストフォージェリ (CSRF)
  • クロスオリジンリソース共有 (CORS)

同一生成元ポリシー (SOP)

相同

まず、同じオリジンが何を意味するのかを説明します。プロトコル、ドメイン名、ポートがすべて同じであり、それが同じオリジンです。

URL相同
https://niconico.comベンチマーク
https://niconico.com/spirit o
https://sub.niconico.com/spirit x
http://niconico.com/spirit x
https://niconico.com:8080/spirit x

制限

クロスドメインの問題が発生する理由は、SOP のさまざまな制限によるものです。しかし、具体的に何が制限されているのでしょうか?

SOP が「非同一オリジンのリソースの取得を制限する」という意味だと言うなら、それは間違いです。最も単純な例は、画像、CSS、JS ファイルなどのリソースを参照するときにクロスドメインが許可されることです。

SOP が「クロスドメイン リクエストを禁止する」という意味だと言う場合、これも間違いです。本質的に、SOP はクロスドメイン リクエストを禁止するのではなく、リクエスト後のリクエストの応答を傍受します。これにより、後述するCSRFが発生します。

実際、SOP は単一の定義ではなく、状況に応じて異なる解釈が行われます。

  • クッキー、DOM、JavaScript の名前付きスコープを制限する
  • iframe、画像、その他のリソースに対するコンテンツ操作を制限する
  • Ajaxリクエストの制限、より正確にはAjaxレスポンス結果の操作の制限は、基本的に前のものと同じです。

実際のアプリケーションで遭遇する可能性のある 3 つの例を以下に示します。

  • Ajaxを使用して他のクロスドメインAPIをリクエストする、最も一般的な状況、フロントエンド初心者の悪夢
  • iframeは親ページと通信し、発生率は比較的低く、解決策は理解しやすい
  • クロスドメイン画像(<img>からの画像など)を操作する場合、キャンバス上の画像を操作するとこの問題が発生します。

SOPがない場合:

  • ブラウザで複数のタブを開くと、データが漏洩します。
  • iframeを使用して銀行のウェブサイトを開くと、ウェブサイトのコンテンツを自由に読み取ることができ、ユーザーが入力したコンテンツを取得できます。
  • より攻撃的なCSRF

クロスドメインをバイパス

SOP はセキュリティをもたらしますが、ドメイン間の要求がある場合があるため、ある程度のトラブルも生じます。スペースの制限とインターネット上に関連記事が多数あるため、ここではクロスドメインの問題の解決策について詳しく説明せず、いくつかのキーワードのみを示します。

アヤックスの場合

  • jsONPの使用
  • バックエンド CORS 構成
  • バックエンドリバースプロキシ

iframeの場合

  • 情報を伝達するにはlocation.hashまたはwindow.nameを使用します
  • postMessageの使用

クロスサイトリクエストフォージェリ (CSRF)

簡単な説明

CSRF(クロスサイトリクエストフォージェリ)は一般的な攻撃方法です。これは、A ウェブサイトが正常にログインした後、Cookie が正常に保存されることを意味します。他のウェブサイト B は、何らかの方法で A ウェブサイトのインターフェイスを呼び出して操作し、A インターフェイスは要求時に自動的に Cookie を取得します。

前述のように、SOP は htmltag を通じてリソースをロードすることができ、また、SOP はインターフェース要求をブロックせず、要求結果を傍受します。CSRF はこれら 2 つを利用します。

したがって、SOP は CSRF を防止する方法として使用することはできません。

GET リクエストの場合、<img> 内に直接配置して、誰にも気付かれずにクロスドメイン インターフェイスをリクエストできます。

POST リクエストの場合、多くの例ではフォーム送信が使用されます。

<form action="<nowiki>http://bank.com/transfer.do</nowiki>" method="POST">
  <input type="hidden" name="acct" value="マリア" />
  <input type="hidden" name="金額" value="100000" />
  <input type="submit" value="私の写真を見る" />
</フォーム>

最終的に、これらの 2 つの方法では、リクエストが HTML によって制御され、JS を使用して結果を直接操作できないため、クロスドメインが報告されません。

SOP と ajax

ajax リクエストの場合、データを取得した後、必要に応じて js 操作を実行できます。この時点では、同一生成元ポリシーにより応答は阻止されますが、リクエストは引き続き行われます。応答のインターセプションを実行するのはバックエンド プログラムではなくブラウザだからです。実際、リクエストはサーバーに送信され、結果が返されていますが、セキュリティ ポリシーにより、ブラウザーは js 操作の続行を許可しないため、「CORS ポリシーによってブロックされました: 要求されたリソースに 'Access-Control-Allow-Origin' ヘッダーが存在しません」というよく知られたメッセージが報告されます。

したがって、同一オリジンポリシーは CSRF を防止する方法として使用することはできないことを再度強調しておきます。

ただし、CSRF を防止できる例外があります。ブラウザはすべてのリクエストが正常に送信されることを許可しません。上記の状況は単純なリクエストに限定されます。関連する知識については、以下の CORS セクションで詳しく説明します。

CSRF対策

SOP は CSRF によって悪用されるので、本当に役に立たないのでしょうか?

いいえ! SOP が Cookie の名前の範囲を制限していることを覚えていますか? リクエストによって Cookie が自動的に取得されますが、攻撃者は Cookie の内容自体を取得することはできません。

したがって、CSRF に対処するための考え方は、トークンを Cookie に書き込み、リクエストを行うときにそのトークンをクエリ、本文、またはヘッダーに含めることです。リクエストがサーバーに到着し、トークンをチェックします。トークンが正しければ、そのリクエストは Cookie を表示できるドメインから送信されたものであるはずです。CSRF はこれを実行できません。 (この方法はフロントエンドとバックエンドを分離するために使用され、バックエンドのレンダリングはDOMに直接書き込むことができます)

サンプルコードは次のとおりです。

var csrftoken = Cookies.get('csrfToken')

関数csrfSafeMethod(メソッド) {
  // これらの HTTP メソッドは CSRF 保護を必要としません
  /^(GET|HEAD|OPTIONS|TRACE)$/.test(メソッド) を返します
}
$.ajaxSetup({
  送信前: 関数(xhr, 設定) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader('x-csrf-token', csrftoken)
    }
  },
})

クロスオリジンリソース共有 (CORS)

クロスドメインはブラウザの制限ですが、サーバーが CORS 関連の構成を設定すると、サーバーに返される情報ヘッダーに Access-Control-Allow-Origin が追加されます。ブラウザは、このフィールドの値が現在のオリジンと一致することを確認すると、クロスドメイン制限を解除します。

HTTP/1.1 200 OK

日付: 2016 年 4 月 24 日 (日) 12:43:39 GMT

サーバー: Apache

アクセス制御許可元: http://www.acceptmeplease.com

キープアライブ: タイムアウト=2、最大=100

接続: キープアライブ

コンテンツタイプ: application/xml

コンテンツの長さ: 423

CORS には 2 種類のリクエストがあります。

簡単なリクエスト

  • リクエストメソッドは GET、POST、または HEAD です。
  • Content-Type は application/x-www-form-urlencoded、multipart/form-data、または text/plain に設定されます

上記の 2 つの条件を満たすすべてのリクエストは CORS シンプル リクエストです。単純なリクエストはサーバーに直接送信されるため、CSRF が発生する可能性があります。

事前飛行リクエスト

単純なリクエストの要件を満たさないリクエストでは、まずプリフライト リクエストを送信する必要があります。ブラウザは、実際のリクエストを行う前に、現在のソースが CORS ターゲットを満たしているかどうかをサーバーに問い合わせる OPTION メソッドを使用してリクエストを送信します。正式なリクエストは、検証に合格した後にのみ送信されます。

たとえば、application/json を使用してパラメータを渡す POST リクエストは単純ではないリクエストであり、事前チェック中にインターセプトされます。

たとえば、PUT メソッド リクエストが使用される場合、事前チェック リクエストも送信されます。

CSRF を防ぐことができる上記の例外は、事前チェック リクエストを指します。クロスドメイン リクエストの事前チェックが成功した場合でも、実際のリクエストは送信できないため、CSRF が成功しないことが保証されます。

CORS と Cookie

同じドメインとは異なり、クロスドメイン CORS リクエストは、デフォルトでは Cookie と HTTP 認証情報を送信しません。フロントエンドとバックエンドの両方で、構成に Cookie を含めるようにリクエストを設定する必要があります。

このため、axios では CORS リクエストを行うときに withCredentials: true を設定する必要があります。

以下は、node.js バックエンド koa フレームワークの CORS 設定です。

/**
 * CORSミドルウェア
 *
 * @param {Object} [オプション]
 * - {String|Function(ctx)} origin `Access-Control-Allow-Origin`、デフォルトはリクエスト Origin ヘッダー
 * - {文字列|配列} allowMethods `Access-Control-Allow-Methods`、デフォルトは 'GET、HEAD、PUT、POST、DELETE、PATCH'
 * - {文字列|配列} exposeHeaders `Access-Control-Expose-Headers`
 * - {文字列|配列} allowHeaders `アクセス制御許可ヘッダー`
 * - {文字列|数値} maxAge `Access-Control-Max-Age`(秒単位)
 * - {ブール値} 資格情報 `Access-Control-Allow-Credentials`
 * - {Boolean} keepHeadersOnError エラーが発生した場合に `err.header` に設定されたヘッダーを追加します
 * @return {Function} corsミドルウェア
 * @api パブリック
 */

以上がJS Same-Origin PolicyとCSRFの詳しい説明です。JS Same-Origin PolicyとCSRFの詳細については、123WORDPRESS.COMの他の関連記事もご覧ください。

以下もご興味があるかもしれません:
  • JavaScript ホモロジー ポリシーとクロスドメイン アクセスの例の詳細な説明
  • JS で実装された Ajax とホモロジー戦略 (例の説明)
  • jsホモロジー戦略の詳細な説明
  • js を使用して 2 つの HTML ウィンドウ間で通信する方法
  • JavaScriptのEventBusはオブジェクト間の通信を実装します
  • vue websocket nodeJS を使用したリアルタイム通信の落とし穴についての簡単な説明
  • Vue.js コンポーネント通信のカスタムイベントの詳細な説明
  • SpringBoot は jsonp クロスドメイン通信メソッドの例を実装します
  • Vue.js の子コンポーネントが親コンポーネントと通信する方法の詳細なコード例
  • SockJS を使用して vue で webSocket 通信を実装するプロセス
  • JavaScript で同一オリジン通信を実装する方法

<<:  Dockerのクイックガイド

>>:  MySQL5.7.17 winx64 インストール バージョン構成方法 Windows Server 2008 R2 でのグラフィック チュートリアル

推薦する

Docker はすべてのコンテナをバッチ起動して閉じます

Dockerの場合すべてのコンテナコマンドを開始する docker を起動します $(docker ...

CSS 垂直センタリングの代替実装コードの詳細な説明(非従来型)

序文ご存知のとおり、「CSS で要素を垂直方向に中央揃えするにはどうすればよいか」という質問は、すで...

iframeを指すaタグのターゲットの名前とIDの違い

コードをコピーコードは次のとおりです。 <iframe id="myFrameId&...

IE6 での背景画像キャッシュ

IE6 での CSS 背景画像のちらつきバグ (IE6 の背景画像キャッシュの問題) IE6 は、背...

Vue2.0/3.0双方向データバインディングの実装原理の詳細説明

Vue2.0/3.0双方向データバインディングの実装原理双方向データバインディングとは、データの変更...

MySQL 5.7.21 解凍バージョンのインストールと設定のグラフィックチュートリアル

この記事では、MySQL 5.7.21の解凍版をダウンロードしてインストールする詳細な手順を記録して...

jQuery ステップ進行軸プラグインの実装コード

毎日のjQueryプラグイン - ステップ進捗軸 ステップ進捗軸ツール系のサイトでは入門チュートリア...

IE で UTF8 エンコードされたページで行が理由もなく空白のままになり、UTF8 ページが表示されない問題の解決方法

理由は、すべてのファイルが utf8 でエンコードされているためです。ファイルがインクルードされると...

ウェブページ制作時のコードコメントの書き方

<br />私の仕事で使用しているアノテーションの書き方の基準をまとめました。技術的な内...

Vue はクリックフリップ効果を実現します

参考までに、vueを使用してクリックフリップエフェクトを簡単に実装します。具体的な内容は次のとおりで...

MySQLクエリトランザクション処理へのノード接続の実装

目次トピックmysqlの追加、削除、変更、クエリを入力しますMySQL トランザクション処理私は M...

Vue 構成リクエストの複数サーバーソリューションの詳細な説明

1. 解決策1.1 インターフェースコンテキストパスの説明2 つのバックエンド インターフェイス サ...

Linux ディスクデバイスと LVM 管理コマンドの詳細な例

序文Linux オペレーティング システムでは、デバイス ファイルは特別なタイプのファイルです。これ...

Reactのref属性を深く理解する方法

目次概要1. Refsオブジェクトの作成1.1 React.createRef() 1.2React...

MySQL の詳細な単一テーブルの追加、削除、変更、クエリの CRUD ステートメント

MySQL の追加、削除、変更、クエリステートメント1. 練習シートを作成するここでの練習表は3つの...