JSONPを提供する側は、生成するJSON部分を、必要に応じて適切にエスケープすべきです。
例えば、攻撃者が何らかの方法で、JSONPの基となるデータをあらかじめJSONPの提供側に与えておき、osakaの天気が要求されたときにはweatherとして「"+alert(1)+"」という文字列が返るようになっていたとします。
このとき、アプリケーション側が「http://example.jp/weather.json?loc=osaka」というURLでJSONPを要求したとすると、
callback( { "city" : "osaka", "weather" : ""+alert(1)+"" } ); |
のようなJSONPが生成されてしまい、アプリケーション側では<script>要素のsrcとして読み込みますので、攻撃者の用意したスクリプトであるalert(1)の部分が実行されてしまいます。
このような問題を防ぐため、JSONPを生成する際には生成する型に応じて適切なエスケープおよび値の検証が必要となります。
JSONP内で生成されるほとんどの値は文字列であると思います。文字列を生成する場合には、半角英数字(a-zA-Z0-9)以外の文字はすべて\uXXXXの形式でエスケープしておくとよいでしょう。
それぞれ、指定された値および数値などに合致しているか確認し、合致していない場合はエラーとするなど、不適切な値がJSONPに含まれないようにします。
アプリケーション側で<script>要素を使ってJSONPを読み込むということは、いいかえるとアプリケーションの外部にあるスクリプトを読み込んでいるということです。前項で書いたように、JSONPの生成においてエスケープに問題がある場合には、JSONP内に攻撃者が用意した悪意のあるスクリプトが挿入されてしまう可能性があります。そのようなJSONPをアプリケーション側でJavaScriptソースとして読み込んだ場合には、ユーザーのブラウザでその悪意のあるスクリプトが動作してしまいます。そのため、アプリケーション側のCookieによる認証情報や、アプリケーション内で扱っている機密情報などが第三者に漏えいするなどの被害が発生する可能性があります。
JSONPを利用するアプリケーションでは、信頼できるサイトのJSONPのみを利用するようにしなくてはいけません(“信頼できるサイト”という定義が難しいのですが……)。
Copyright © ITmedia, Inc. All Rights Reserved.