JSONPとは何か:レガシーな技術に潜むセキュリティリスク
JSONPとは、同一生成元ポリシーを回避してクロスドメイン通信を実現するための古い手法である。
JSONPの概要
Webアプリケーションの世界では、「同一生成元ポリシー(Same-Origin Policy, SOP)」という強力なセキュリティルールが存在する。これは、異なるドメイン間でのJavaScriptによるリソースアクセスを制限し、悪意あるサイトからのデータ窃取を防ぐための仕組みだ。例えば、example.comのスクリプトはapi.other.comのデータを直接取得できない。この制約を回避するために考案されたのが**JSONP(JSON with Padding)**である。
JSONPは、XMLHttpRequest(XHR)ではなく<script>タグを利用してデータを取得する。スクリプトタグはSOPの制約を受けないため、異なるドメインからJavaScriptを読み込むことが可能である。これを利用し、APIサーバーがJavaScriptコードとしてデータを返すことで、クライアントがそれを実行してデータを取得するという仕組みだ。
具体的なリクエストの流れは以下のようになる。
// クライアント側
function handleResponse(data) {
console.log(data);
}
var script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);
サーバーは次のようなレスポンスを返す。
handleResponse({ "message": "Hello, world!" });
こうして、ブラウザはhandleResponse関数を実行し、データを安全であるかのように扱うことができる。だが、ここにこそ脆弱性が潜んでいる。
JSONとJSONPの違い
| 項目 | JSON | JSONP |
|---|---|---|
| データ形式 | 純粋なデータ(例: { "a": 1 }) |
JavaScriptコード(例: callback({ "a": 1 })) |
| 送信方法 | XHRやfetch APIなど |
<script>タグを動的生成 |
| セキュリティ | SOPの対象 | SOPの制限を回避できる |
| パース方法 |
JSON.parse()で解析 |
自動実行(関数として呼び出される) |
| 現在の推奨度 | 高(標準) | 低(非推奨) |
つまり、JSONはデータであり、JSONPはスクリプトだ。JSONPを読み込むと、ブラウザはそれを即座に実行する。これにより、サーバーが返すコードが意図しない内容だった場合、悪意あるスクリプトがそのまま実行されてしまう可能性がある。
JSONPは使うべきか?
結論から言えば、使わないほうがいい。理由はシンプルで、セキュリティ面において非常に脆弱だからだ。JSONPは、XSS(クロスサイトスクリプティング)の一種である「スクリプトインジェクション攻撃」に対して無防備である。攻撃者がcallbackパラメータを細工して悪意ある関数を呼び出すようにすれば、任意のJavaScriptコードが実行されてしまう。
なぜJSONPが危険なのか
- スクリプトとして実行されるため、データではなくコードとして扱われる。
-
入力検証を怠ると、
callbackパラメータを悪用して任意コード実行が可能。 - **CSRF(クロスサイトリクエストフォージェリ)**の温床にもなり得る。
以下は、JSONPがどのように悪用されうるかを示した図である。
このような危険を孕んでいるため、現代のWeb開発ではJSONPはほぼ使われない。代わりに、**CORS(Cross-Origin Resource Sharing)**が標準的な手段として用いられている。CORSを使えば、サーバーが特定のオリジンを許可し、安全にクロスドメイン通信を行うことができる。
JSONPの終焉とCORSの台頭
CORSは、サーバーがレスポンスヘッダに以下のような設定を行うことで、特定のオリジンからのアクセスを許可する仕組みだ。
Access-Control-Allow-Origin: https://example.com
これにより、クライアントは通常のfetchやXMLHttpRequestを使って安全にデータを取得できる。CORSはHTTPレベルで制御され、ブラウザがセキュリティを担保してくれるため、JSONPのようにスクリプト実行のリスクがない。
一方で、古いAPIやレガシーシステムでは、いまだにJSONPをサポートしている場合がある。そのような場合でも、可能な限りCORS対応へ移行するのが望ましい。どうしてもJSONPを使わざるを得ない場合は、以下の対策を講じる必要がある。
-
callbackパラメータをホワイトリスト化し、任意の関数名を指定できないようにする。 - サーバー側で返却するスクリプト内容を厳密にエスケープする。
- APIの利用を内部ネットワークのみに制限する。
まとめ
JSONPは、ブラウザがCORSをサポートしていなかった時代に、クロスドメイン通信を可能にするための「苦肉の策」だった。しかし、現代のセキュリティ標準では明確に時代遅れであり、使用すべきではない技術に分類される。安全なWebアプリケーションを構築するためには、JSONPではなくCORSや安全なAPI認証方式(例: OAuth2)を採用することが必須である。
過去の遺産から学ぶことは重要だ。JSONPは「制約を回避する創意工夫の産物」であると同時に、「セキュリティ意識の低さがもたらす危険性の象徴」でもある。エンジニアとして、どちらの面からも学びを得ることができる技術だ。