こんにちは。セキュリティの世界へようこそ。
日々、コードの海を泳ぐエンジニアの皆さん、お疲れ様です。今日は、かつてWebの「魔法の杖」と呼ばれ、今は「パンドラの箱」となってしまったJSONPという技術と、その現代的な後継者であるCORSについてお話しします。
「セキュリティの話なんて、堅苦しくて頭が痛くなる…」そんなふうに思っていませんか? 大丈夫です。泥棒が家に侵入する仕組みをイメージしながら、一緒に紐解いていきましょう。
—
1. JSONPは「合鍵を玄関マットの下に置く」ようなもの?
JSONP(JSON with Padding)という言葉、レガシーなシステムを触っていると耳にすることがありますよね。
もともとブラウザには「自分と同じドメインのサーバーとしか通信しちゃダメ(同一オリジンポリシー)」という厳格なルールがあります。でも、昔のエンジニアは「外部のサーバーからもデータをもらいたい!」と切実に願っていました。そこで生まれたのがJSONPです。
なぜ危ないのか?
JSONPは、サーバーから送られてきたデータ(JSON)を、ブラウザでタグとして読み込むことで実行します。
これを家の防犯に例えてみましょう。
- 本来の通信: 厳重な鍵をかけた玄関ドアを通して、身元が確かな人だけが荷物を届ける。
- JSONPの仕組み: 「誰でもいいから、この合鍵(スクリプト)を持ってきてくれたら、家のドアを全開にするよ!」と宣言しているようなものです。
もし、その「合鍵」を悪い泥棒がすり替えていたら? あなたのブラウザという「家」の中で、泥棒が書いた悪意ある命令(XSS攻撃)が、まるであなたの自筆の命令かのように実行されてしまうのです。これがJSONPの最大のリスクです。
---
2. 現代の守護神「CORS」というスマートな防犯システム
そこで登場するのがCORS(Cross-Origin Resource Sharing)です。CORSは、JSONPのような「とりあえず全部許可する」という無茶なやり方ではなく、「誰が、どこから、何をしてもいいか」をサーバーが細かく指定する仕組みです。
これは、最新のスマートホームの防犯システムに似ています。
- 「隣の家(ドメインA)の住人は、リビングのカメラ(API)を見てもいいけど、寝室(DB)には入っちゃダメ」
- 「知らない人(許可されていないドメイン)は、そもそも玄関のチャイムも鳴らせない」
このように、ブラウザとサーバーの間で「許可証」を確認し合うのがCORSの役割です。
---
3. CORSを正しく設定しよう:実戦的なコード例
CORSを使うには、サーバーからレスポンスを返す際に、特定のHTTPヘッダーを付与します。ここが防御の要です。
サーバー側(Node.js/Expressの例)での設定
const express = require('express');
const app = express();
app.use((req, res, next) => {
// 1. 許可するドメインを指定( は危険!できるだけドメインを限定しましょう)
res.header("Access-Control-Allow-Origin", "https://your-trusted-site.com");
// 2. 許可する通信手段(GETだけなのか、POSTも必要なのかを絞る)
res.header("Access-Control-Allow-Methods", "GET, POST");
// 3. 許可するヘッダーを指定
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
ここがポイント!
Access-Control-Allow-Origin: と書けば確かに楽ですが、これだと「世界中の泥棒にドアを開ける」のと同じです。必ず「信頼できるドメイン」だけを記載する癖をつけましょう。
---
4. 一歩ずつ、安全な開発を
「JSONPを使わないと動かない古い機能があるんだけど…」という現場もあるかもしれません。そんな時は、「なぜ危険なのか」をチームで共有し、少しずつ現代的なAPI通信へ移行する計画を立てるのが、プロのエンジニアの第一歩です。
セキュリティは、一度設定したら終わりではありません。家の鍵を定期的に点検するように、自分たちのコードが「誰に対してドアを開けているのか」を常に意識してみてください。
わからないことがあっても大丈夫。一歩ずつ、一緒に学んでいきましょう。皆さんの書くコードが、誰かの大切なデータを守る盾になりますように!
コメント