<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="5" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[5]</anchor-end> <dfn><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor></dfn> は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> を <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数</anchor>の呼び出しの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>として記述する
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">括弧</anchor>で括る) ことによって異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">起源</anchor>に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求</anchor>を送信し、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>を受信する技法です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="6" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[6]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CORS</anchor> が実装される前に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">同一起源ポリシー</anchor>の抜け道として広く
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webアプリケーション</anchor>によって利用されていました。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">セキュリティーホール</anchor>の温床であることもあり、現在ではあまり使われず、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CORS</anchor> を利用するのが一般的となっています。</p><section><h1>代替</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="34" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[34]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> はほぼ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">セキュリティーホール</anchor>であり、望ましくないと考えられています。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[39]</anchor-end> 元々公開されていて漏洩してもまったく問題のないデータならセキュリティー問題にはなりませんが、
古い時代の裏技的な手法ですから、今時敢えて使うメリットはまったくありません。
問題があるかないか微妙な場合に判断を誤るリスクを考えると、
避けておくのが無難でしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="40" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[40]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>上で異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">起源</anchor>のデータを取得するには、 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Fetch API</anchor> を使うことができます。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Fetch API</anchor> に対応していない <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>を想定するなら、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">XHR</anchor> を使うことができます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="41" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[41]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>で異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">起源</anchor>からのデータの取得に対応させるには、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CORS</anchor> を使う必要があります。</p></section><section><h1>構文</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="35" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[35]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> としても解釈可能な <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> データを <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数</anchor>呼び出しの形で表現したものと理解されています (が、
正式な規定はなく、厳密な定義は不明です)。</p><figure class="railroad"><ol><li>*<ol><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">空白</anchor></li></ol></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor></li><li>*<ol><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">空白</anchor></li></ol></li><li><code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(</anchor></code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONテキスト</anchor></li><li><code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">)</anchor></code></li><li>*<ol><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">空白</anchor></li></ol></li></ol></figure></section><section><h1><code class="URI" xml:lang="en">callback</code> 引数</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">query</anchor> 部
(<code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">application/x-www-form-urlencoded</anchor></code>) の
<dfn><code class="URI" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">callback</anchor></code></dfn> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>によって指定されたものを使うことが慣例となっています。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は通常は (その用途からしても) <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code>
で使うものですが、 <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">POST</anchor></code> でも<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求</anchor>を受け付けている場合、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求メッセージ</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">メッセージ本体</anchor>の <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">application/x-www-form-urlencoded</anchor></code>
や <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">multipart/form-data</anchor></code> の <code class="URI" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">callback</anchor></code>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>でも指定を受け付けることがあります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[12]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>として任意の文字列を受け付けると、任意の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor>
コードの注入を許してしまうことになり、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">脆弱性</anchor>となります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> の生成者は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>として使える<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>を限定し、
使えない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が含まれていると<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エラー</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>を返したり、
既定の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>で返したりする必要があります。実装によっては通常の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor>
を返すかもしれません。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="26" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[26]</anchor-end> その範囲は実装により異なります。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> 側のライブラリーの仕様にもよります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">オブジェクト</anchor>の階層の深いところにある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数</anchor>を呼び出すために <code xmlns="http://www.w3.org/1999/xhtml">.</code> を、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">配列</anchor>内の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数</anchor>を呼び出すために <code xmlns="http://www.w3.org/1999/xhtml"><em>[</em></code> や <code xmlns="http://www.w3.org/1999/xhtml"><em>]</em></code>
を認めることもあります。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[13]</anchor-end> <code class="URI" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">callback</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>やそれに相当する指定がない場合の動作は実装により異なります。
通常の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> で返すことやエラーの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応答</anchor>を返すこともあれば、既定の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>で返すこともあります。</p></section><section><h1>JSON との互換性</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="14" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[14]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> と <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">オブジェクトリテラル</anchor>は、
厳密には構文的に違いがあります。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>JSON</anchor> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="45" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[45]</anchor-end> 
ですからただ単に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の前後に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数名</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">括弧</anchor>を連結するだけでは、
正しい <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> コードとならず、構文エラーになる可能性があります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="15" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[15]</anchor-end> これを避けるためには、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の生成時、または <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> から <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor>
への変換時にいくつかの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">エスケープ</anchor>しなければなりません。
しかしそれをしていない実装もあり、ある種の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">脆弱性</anchor>となるかもしれません。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="27" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[27]</anchor-end> 実際に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> を使った <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webアプリケーション</anchor>には特定の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>を入力として与えると誤動作するものがあります。</comment-p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="37" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[37]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="36" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;36</anchor-internal> は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>と <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>で使える<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>の比較です。<refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="36" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[36]</anchor-end> <cite xml:lang="en">Compare character sets &quot;$es5:DoubleStringCharacter-char&quot; and &quot;$ecma404:string-char&quot;</cite> (<time>2015-06-12 22:47:17 +09:00</time> 版) <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://chars.suikawiki.org/set/compare?expr1=%24es5%3ADoubleStringCharacter-char&amp;expr2=%24ecma404%3Astring-char">http://chars.suikawiki.org/set/compare?expr1=%24es5%3ADoubleStringCharacter-char&amp;expr2=%24ecma404%3Astring-char</anchor-external></li></ul></refs></comment-p></section><section><h1>MIME 型</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[7]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> のコードですから、 <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">text/javascript</anchor></code>
が適切と考えられます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="8" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[8]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSON</anchor> の変種であるとして、 <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">application/json</anchor></code>
が指定されることもあります。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="29" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[29]</anchor-end> この指定は必ずしも正しいとは言えませんが、 <code xmlns="http://www.w3.org/1999/xhtml" class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">application/json</anchor></code>
を表示するビューアーの類の中には <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> に対応しているものもあり、
有用なこともあるかもしれません。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="9" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[9]</anchor-end> また <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">text/html</anchor></code> や
<code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">text/plain</anchor></code>、 <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Content-Type:</anchor></code>
なしなどで送信されることもあります。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="28" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[28]</anchor-end> <code xmlns="http://www.w3.org/1999/xhtml" class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">text/html</anchor></code> や <code xmlns="http://www.w3.org/1999/xhtml" class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">text/plain</anchor></code>
を使うのは明らかに誤りであり、避けるべきです。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="30" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[30]</anchor-end> いずれにせよ、 <code class="MIME" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">charset</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>が指定されることもあります。</p></section><section><h1>JSONP による情報漏洩</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="16" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[16]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> に含まれる情報が秘密の情報である場合、第三者に情報が漏洩する危険性があります。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[17]</anchor-end> 例えばある会員制サイトが、アクセスした<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>自身の会員登録情報を返す <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor>
を用意しているとします。
悪意のあるサイトはその <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> を取得して内容を自サイトに送信するコードを書くことで、
同サイトを閲覧した利用者が気づかないうちに会員制サイトの登録情報を取得できます。</p></example></section><section><h1>JSONP による CSRF</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[18]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">起源</anchor>に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要求</anchor>を送信し、特定の処理を実行してその結果を得るために用いられることがあります。
その素朴な実装は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">CSRF</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">脆弱性</anchor>そのものです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="19" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[19]</anchor-end> 特に、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> では特定の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の <code class="HTTP" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GET</anchor></code> だけで処理を実行させられますから、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> の記述や実行が認められていなくても、 <code class="HTMLe" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">img</anchor></code>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要素</anchor>の <code class="HTMLa" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">src</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">属性</anchor>に指定するなどより簡易な方法で呼び出せてしまいますので、
より深刻な問題となる可能性があります。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[20]</anchor-end> 例えば <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> に指定した文字列を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">掲示板</anchor>に投稿できる <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> が存在するとします。また、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor> は記述できないものの、
末尾が <code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">.jpg</anchor></code> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> を貼り付けると <code class="HTMLe" xml:lang="en"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">img</anchor></code>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">要素</anchor>に変換される <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SNS</anchor> があるとします。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> の末尾が
<code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">.jpg</anchor></code> になるようにし、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SNS</anchor> に貼り付けると、その <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SNS</anchor>
を表示するたびに、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>が気づかないうちに自動的に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">掲示板</anchor>に投稿されてしまいます。</p></example></section><section><h1>歴史</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="21" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[21]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は、2005年12月5日に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bob Ippolito</anchor> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ブログ</anchor>で提案 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;4</anchor-internal></src>
しました。呼称の由来は「JSON with Padding」<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;4</anchor-internal></src> だといいます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="23" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[23]</anchor-end> なお <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">query引数</anchor>の名前は <code>jsonp</code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;4</anchor-internal></src> とされていました。
後に普及することになる <code>callback</code> はまだ使われていませんでした。</p><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[4]</anchor-end> <cite xml:lang="en">Remote JSON - JSONP</cite>
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bob Ippolito</anchor> 著, <time>2013-09-18 23:18:57 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/">http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/</anchor-external><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[22]</anchor-end> 元の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">URL</anchor> は <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp">http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp</anchor-external>
だったようです。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="3" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[3]</anchor-end> <cite xml:lang="en">JSONP: JSON With Padding - Ajaxian</cite>
( (<time>2011-12-03 15:06:37 +09:00</time> 版))
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://ajaxian.com/archives/jsonp-json-with-padding">http://ajaxian.com/archives/jsonp-json-with-padding</anchor-external></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[1]</anchor-end> <cite>TAKESAKO @ Yet another Cybozu Labs: Operaでも非同期リクエストが並列処理できる img-JSONP</cite> (<time>2008-11-26 11:37:10 +09:00</time> 版) <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://labs.cybozu.co.jp/blog/takesako/2007/06/opera_img-jsonp.html">http://labs.cybozu.co.jp/blog/takesako/2007/06/opera_img-jsonp.html</anchor-external></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[2]</anchor-end> <cite>JSONP が Opera だと非同期処理できない - 川o・-・)&lt;2nd life</cite> (<time>2009-02-09 18:00:12 +09:00</time> 版) <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://d.hatena.ne.jp/secondlife/20060906/1157515075">http://d.hatena.ne.jp/secondlife/20060906/1157515075</anchor-external></li></ul></refs><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[24]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">デファクト標準</anchor>であり、仕様書と呼べるものは存在していません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="25" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[25]</anchor-end> 個別の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Web API</anchor> の実装仕様の類を除けば、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JSONP</anchor>
を採用している仕様には次のものがあります。<figure class="short list"><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">revokeエンドポイント</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 7009</anchor>)</li></ul></figure></p><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="31" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[31]</anchor-end> <cite xml:lang="en">Draft 1: OAuth Extension for Response Data Format - Draft 1</cite>
(<time>2008-09-10 03:31:09 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://oauth.googlecode.com/svn/spec/ext/response_data_format/1.0/drafts/1/oauth_response_data_format_ext.html#processing">http://oauth.googlecode.com/svn/spec/ext/response_data_format/1.0/drafts/1/oauth_response_data_format_ext.html#processing</anchor-external></figcaption><blockquote><p>When requesting the response data format as &quot;JSON&quot;, the Consumers MAY pass the 'xoauth_json_callback' with the JSONP callback and the Service Provider MUST return a JSONP callback using the value from the 'xoauth_json_callback' parameter.</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> <cite xml:lang="ja">Instagram API Endpoints • Instagram Developer Documentation</cite>
(<time>2015-03-05 16:50:30 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://instagram.com/developer/endpoints/#jsonp">https://instagram.com/developer/endpoints/#jsonp</anchor-external></figcaption><blockquote><p>If you're writing an AJAX application, and you'd like to wrap our response with a callback, all you have to do is specify a callback parameter with any API call:</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> <cite>Responses &amp; Errors</cite>
(<time>2015-03-05 17:39:32 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://developer.foursquare.com/overview/responses">https://developer.foursquare.com/overview/responses</anchor-external></figcaption><blockquote><p>To use JSONP, add a callback=XXX parameter to your request and we will respond with XXX(response). In the case of JSONP, we always return 200 (except in the case of 500’s) so the brower will allow the response to be handled by your code, but the true HTTP response code can be obtained from the code in the meta response.</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="32" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[32]</anchor-end> <cite>Response Formats</cite>
(<time>2012-09-26 04:52:48 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://pic.photobucket.com/dev_help/WebHelpPublic/Content/Getting%20Started/ResponseFormats.htm">http://pic.photobucket.com/dev_help/WebHelpPublic/Content/Getting%20Started/ResponseFormats.htm</anchor-external></figcaption><blockquote><p>To use, set &quot;format=jsonp&quot;, and specify a callback function name in the jsonp_callback parameter. The callback can be word characters and dot, supporting OO code.</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="33" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[33]</anchor-end> <cite>WooCommerce REST API Documentation v2</cite>
(<time>2015-03-11 03:10:19 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://woothemes.github.io/woocommerce-rest-api-docs/#jsonp-support">http://woothemes.github.io/woocommerce-rest-api-docs/#jsonp-support</anchor-external></figcaption><blockquote><p>You can specify the callback using the ?_jsonp parameter for GET requests to have the response wrapped in a JSON function:</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="38" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[38]</anchor-end> <cite xml:lang="en">JSON callbacks | Alfresco Documentation</cite>
(<time>2015-07-14 23:37:23 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://docs.alfresco.com/4.2/concepts/ws-json-callbacks.html">http://docs.alfresco.com/4.2/concepts/ws-json-callbacks.html</anchor-external></figcaption><blockquote><p>A callback is invoked by adding the following URL query parameter to the web script request:</p><p>alf_callback=&lt;function&gt;</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="42" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[42]</anchor-end> <cite xml:lang="en">Abusing JSONP with Rosetta Flash</cite>
( (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Michele Spagnuolo</anchor>著, <time>2017-03-10 12:48:46 +09:00</time>))
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/">https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/</anchor-external></figcaption><blockquote><p>To be also protected from content sniffing attacks, prepend the reflected callback with /**/. This is exactly what Google, Facebook and GitHub are currently doing.</p></blockquote></figure><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="43" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[43]</anchor-end> <cite>JSONP Sandboxを使ったXSS - 金利0無利息キャッシング – キャッシングできます - subtech</cite>
(<time>2017-04-26 01:25:54 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://subtech.g.hatena.ne.jp/mala/20140120/1390227002">https://subtech.g.hatena.ne.jp/mala/20140120/1390227002</anchor-external></p><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="44" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[44]</anchor-end> <cite>カーセンサー | APIリファレンス | リクルートWEBサービス</cite>
(<time>2017-04-28 17:40:10 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://webservice.recruit.co.jp/carsensor/reference.html">https://webservice.recruit.co.jp/carsensor/reference.html</anchor-external></figcaption><blockquote><p>format	レスポンス形式	レスポンスをXMLかJSONかJSONPかを指定します。JSONPの場合、さらにパラメータ callback=コールバック関数名 を指定する事により、javascript側コールバック関数の名前を指定できます。	 	初期値:xml。xml または json または jsonp。</p></blockquote></figure></section></body></html>