こんにちは。セキュリティの世界へようこそ。
現場で泥臭いインシデント対応をしていると、「教科書には載っていないけれど、実はここが一番狙われるんだよな」というポイントによく出くわします。
今日は、Web開発の現場で意外と見落とされがちな「JSONPの罠」についてお話しします。「JSONP? 何それおいしいの?」という方も、家の鍵に例えながら一緒に紐解いていきましょう。
—
1. JSONPって何? 家の鍵で例えると…
まず、JSONPとは「本来は別のサーバーからデータをもらってはいけない(ドメインの壁がある)」というWebの厳しいルールを、「特別な合言葉」を使って突破する仕組みのことです。
これを家に例えてみましょう。
あなたは自分の家(Aサイト)に住んでいますが、隣の家(Bサイト)から「美味しいピザ(データ)」を届けてもらいたいとします。でも、あなたの家の玄関は頑丈で、知らない人からの受け取りはできません。
そこで、Bサイトはこう言います。
「分かった。じゃあ、君が指定した『ピザを受け取る専用の係員(コールバック関数)』を呼ぶから、その人にピザを渡すね!」
この「係員の名前」を教えて、その名前で呼んでもらうのがJSONPのやり取りです。
—
2. なぜ危ないの? 「なりすまし係員」の登場
ここで悪意ある泥棒(攻撃者)が登場します。攻撃者は、あなたの家の玄関に細工をします。
「ねえねえ、さっきのピザ、届けてくれる係員だけど、本当は『ピザ係』じゃなくて『家の中の宝石を全部持ち出す係』にしてくれない?」
もし、Bサイト(サーバー)がこのお願いを鵜呑みにして、「了解!じゃあ『宝石を持ち出す係』を呼ぶね!」と言ってしまったらどうなるでしょう。あなたの家のブラウザ(ブラウザ)は、その命令を「はい、分かりました!」と実行してしまいます。
これがJSONPにおけるXSS(クロスサイトスクリプティング)の正体です。
サーバー側が、送られてきた「係員の名前(コールバック関数名)」をチェックせずにそのまま返してしまうことで、攻撃者が好きなJavaScriptコードを実行できてしまうんです。
—
3. 脆弱なコード例:泥棒を招き入れている状態
例えば、サーバー側で以下のような処理をしていませんか?
// 危険な実装例(Node.js/Express風)
app.get(‘/api/data’, (req, res) => {
const callbackName = req.query.callback; // ここに攻撃者が悪意あるコードを仕込む
const data = { status: “success”, message: “こんにちは!” };
// 警告!受け取った名前をそのままレスポンスに埋め込んでいる
res.send(${callbackName}(${JSON.stringify(data)}));
});
もし、攻撃者が ?callback= というURLを送りつけたら、ブラウザは「ああ、そういう名前の係員なんだね」と勘違いして、そのコードを実行してしまいます。
—
4. どうやって守る? 「身分証の確認」と「現代のルール」
では、どうすればこの泥棒を追い出せるのでしょうか。対策は大きく分けて2つあります。
対策①:係員の名前を厳しくチェックする(ホワイトリスト)
「どんな名前でもいいよ」ではなく、「あらかじめ登録された係員リストに載っている名前だけ受け付ける」というルールにします。
// 安全な実装例
const allowedCallbacks = [‘myCallback’, ‘dataHandler’];
app.get(‘/api/data’, (req, res) => {
const callbackName = req.query.callback;
// リストに存在するかチェック!
if (!allowedCallbacks.includes(callbackName)) {
return res.status(400).send(‘不正なコールバック関数名です’);
}
res.send(${callbackName}(${JSON.stringify(data)}));
});
対策②:そもそも「JSONP」を使わない(これが一番の近道!)
実は、今はもうJSONPを使う必要はほとんどありません。現代のWeb開発ではCORS(Cross-Origin Resource Sharing)という、より安全で標準的な「身分証確認システム」が使われています。
CORSを使えば、サーバー側で「このドメインから来た人ならピザを渡していいよ」と許可リストを書くだけで済みます。
// サーバーの応答ヘッダーにこれを含めるだけでOK
Access-Control-Allow-Origin: https://your-website.com
—
最後に:一歩ずつ進めば怖くない
「JSONPの脆弱性」と聞くと難しく感じるかもしれませんが、要は「相手から言われた名前を、自分の家の中で不用意に実行させない」という、ごく当たり前の防犯意識が大切なんです。
もし今、古いシステムでJSONPを使っているなら、まずは「今のコールバック名は許可リストに入っているか?」を確認してみてください。それだけでも、立派なセキュリティの第一歩です。
分からないことがあれば、いつでも相談してくださいね。技術の進歩は速いですが、基本を押さえれば泥棒には負けませんよ!
コメント