質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JSONP

JSONP(JSON with padding)は、JSONを使用した関数呼び出しのための仕組み。クロスドメインでのデータの受け渡しが可能です。JavaScriptからクロスドメインで容易にデータを扱うことができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

736閲覧

JSONP利用時のCSRF対策

退会済みユーザー

退会済みユーザー

総合スコア0

JSONP

JSONP(JSON with padding)は、JSONを使用した関数呼び出しのための仕組み。クロスドメインでのデータの受け渡しが可能です。JavaScriptからクロスドメインで容易にデータを扱うことができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/09/04 12:30

###前提・実現したいこと
CSRFの仕組みを理解し、JSONPを利用するときにセキュリティ対策する

###発生している問題・エラーメッセージ

CSRFの仕組みが分からない。 下記2番の「アクセスできる」、というのはログインしたからだと理解できるが、 そのあとの「取得する」という行為が何故できるのかわからない。 スクリプト例などを載せて具体的に仕組みを教えて頂ければ幸いです。

###該当のソースコード

1.サイトAにログイン済みの被害者が攻撃者の用意した悪意あるスクリプト(スクリプトBとする)が埋め込まれたWebページにアクセスする。 2.スクリプトBはJavaScriptから機密情報を保持したサービスA(JSONP)にアクセスして、これを取得する。1で被害者はサイトAにログイン済みのため、サービスAには問題なくアクセスできる。←被害者は意図せずサービスAにアクセスしてしまう=CSRF脆弱性! 3.スクリプトBはサービスAから取得した機密情報を攻撃者のサイトに(XmlHttpRequest等を使って)送る。←機密情報の漏えい!! (引用元:https://www.ark-web.jp/blog/archives/2007/01/web20jsonp.html)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ヘソクリの在処と金額を管理しているサービス H が https://hesokuri.example.com/ で展開されているとしましょう。これとは別に統合資産管理サービス S が https://shisan.example.com/ で展開されています。サービス H はヘソクリ情報にアクセスできる API を JSONP で提供しており、サービス S もこの API を利用し、ヘソクリ以外の資産も含めて統合的に管理できる機能をユーザに提供しています。

A さんは、サービス H とサービス S を両方利用しています。

  1. A さんがサービス H にログインし、資産管理ページ、https://shisan.example.com/kanri にアクセスしたとします。
  2. ここでサイト H は https://hesokuri.example.com/checkUserStatus?site=shisan にリダイレクトするよう A さんのブラウザに返します。
  3. するとブラウザからサイト H にリクエストが飛びます。
  4. サイト H では、checkUserStatus が呼ばれたら、クエリストリングの site が事前に登録されているものかチェックします。shisan は正規の提携先として登録されているのでよしとします。
  5. 次にリクエストしてきたユーザがログイン済みかをチェックします。ログイン済みでないならログイン画面を出し、ログインさせます。あと、サービス S がサービス H 内の A さんのヘソクリ情報にアクセスするのを許可するかどうかを聞く画面を出します。ここでは、A さんがログイン状態になり、サービス S にヘソクリ情報を使ってもいいと許可したことにします。
  6. サイト H は、A さんが「許可」ボタンを押した後のページとして、HTML を返さず、代わりに https://shisan.example.com/accepted/ にリダイレクトするよう指示を出します。この元のサービスに戻る URL は、最初の site=shisan に紐付くデータとして、サイト H のデータベースに格納されています。
  7. ブラウザは https://shisan.example.comn/accepted にリダイレクトします。
  8. サイト S では、資産管理画面を出します。この画面の html 中に、<script src="https://hesokuri.example.com/getHesokuriInfo.js?callback=listHesokuriInfo" /> というタグが含まれています。
  9. A さんのブラウザがこの html をレンダリングしようとすると、https://hesokuri.example.com/getHesokuriInfo.js?callback=listHesokuriInfo へのアクセスが発生します。このリクエストには、ログイン認証済みの証しが cookie に載って飛びます。(JSONP 呼び出し)
  10. サイト H は、cookie の情報に基づき、A さんのヘソクリ情報をデータベースから取得し、listHesokuriInfo([{ place: "冷凍庫の製氷機の下", amount: 150000}]); を返します。A さんは製氷機の下に 15 万円隠しているようです。もちろん、この関数名は、JSONP 呼び出しのときの callback パラメータで渡ってきた値を利用しています。
  11. ブラウザでは返ってきた JavaScript を評価するわけですが、listHesokuriInfo([{ place: '冷凍庫の製氷機の下', amount: 150000}]); なので、この関数の実行となります。これは 8. で返ってきた html の中で、JSONP 呼び出しより前に定義されている関数です。サイト S の資産管理画面の該当部分にやってきたデータをはめこんだりします。

まあ、これが JSONP で API を提供しているサイト H と、それを利用したサービスを展開するサイト S の連携です。

で、これを悪用するのがサイト N https://nusutto.example.com/ です。

  • A さんがログイン状態で https://nusutto.example.com/ を踏んでしまったとしましょう。
  • サイト N では画面を html で返しますが、この html 中に、<script src="https://hesokuri.example.com/getHesokuriInfo.js?callback=sendHesokuriInfo" /> というタグが含まれています。
  • A さんのブラウザがこの html をレンダリングしようとすると、https://hesokuri.example.com/getHesokuriInfo.js?callback=send へのアクセスが発生します。このリクエストには、ログイン認証済みの証しが cookie に載って飛びます。(JSONP 呼び出し)
  • サイト H は、cookie の情報に基づき、A さんのヘソクリ情報をデータベースから取得し、sendHesokuriInfo([{ place: "冷凍庫の製氷機の下", amount: 150000}]); を返します。(CSRF 成功)
  • ブラウザでは返ってきた JavaScript を評価するわけですが、sendHesokuriInfo([{ place: '冷凍庫の製氷機の下', amount: 150000}]); なので、この関数の実行となります。サイト N が用意しているこの関数は、盗んだヘソクリ情報をあれこれ悪用します。

CSRF 攻撃は、ブラウザからのアクセスからは正規のものと非正規のものとが区別できない、ということから可能になってしまいます。CSRF 対策は、けっきょく、正規の一連の流れの中におけるリクエストなのか、を判断するしかありません。一般には、CSRF 対策が必要なページに先立つページでトークンを発行し、WEB アプリ側のセッションに格納しておきます。CSRF 対策が必要なページでトークンがリクエストに乗る仕組みにしておき、リクエストが来たときにそこに乗っているトークンとセッションに格納したトークンが一致すれば正規のリクエストとすることで、CSRF を防ぐことができます。
JSONP はそもそもそういう流れがないクロスドメイン API ですが、先立ってトークンを用意しておいて、あとでリクエスト時に渡されるトークンとの一致で見るしかないかと思います。やりかたはいろいろあると思いますが、たとえば、先の正規の流れの 6. のところでサイト H が返すリダイレクト先を https://shisan.example.com/accepted/?token=x2032 とすることかと思います。トークンの実際の値は 5. の段階で発行し、セッションにも格納しておきます。で、サイト S が 8. で JSONP を呼び出す際、このトークンを利用し、<script src="https://hesokuri.example.com/getHesokuriInfo.js?callback=listHesokuriInfo&token=x2032" /> というタグを生成する、と。

かなり適当に書いたので穴はあるかもしれませんが、どうでしょうか。

投稿2017/09/04 14:47

unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/09/06 12:01

ご回答ありがとうございます。 おかげさまで、一連の流れが理解できました。 CSRF対策の説明文で出てくる「トークン」とはなんですか? googleで調べたのですが、解説サイトによって意味がまちまちでした。
unau

2017/09/06 12:11

トークンは文脈によっていろいろな意味がありますので。「トークン」だけでググっても混乱するだけかもしれません。CSRF 対策では、チェックすべきリクエストに乗ってくる秘密の文字列のことで、これがセッション中に格納してあるものと同じかどうかで正しいリクエストか判定するものです。CSRF は、本来の「正しい」フローではないリクエストが成立してしまうことが問題なわけです。チェックすべきリクエストの前のリクエストで秘密の文字列、すなわちトークンをサーバで生成し、それをセッションに格納するとともにクライアントに返します。クライアントが正規のトークンを送ってきた、ということは、その前に「正しい」リクエストを経たことがわかります。
退会済みユーザー

退会済みユーザー

2017/09/06 12:25

分かりました。丁寧な解説有難うございます。
unau

2017/09/06 14:18

通常の WEB アプリでは、Cross Site な Request を防げばいいわけですが、JSONP は Cross Site な Request が正常なリクエストですから、Cross-Site Request Forgeries (CSRF) を防ぐのは本質的に難しいですよね。
guest

0

JSONPは、もともとクロスドメインを突破するために編み出された技術です。

XMLHttpRequestがクロスドメインでの通信に対応していなかった頃にも、<script>タグはドメインを問わず使えたので、「これを使って通信してしまおう」と考えた人がいました。

javascript

1callback({"foo": "bar" /* さらにJSONデータが続く */});

JSONPのリクエストをかけると、上のようなレスポンスが返ってきます。<script>タグでこれを読み取れば、callback関数が、JSONデータを引数として実行されることで、データを伝える、という流れです。

<script>要素は昔からあったこともあって、CSPなどで意図的に設定しない限り、どこのドメインのでもアクセス可能なのです。

投稿2017/09/04 12:48

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/09/06 11:44

ご回答ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問